??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲国产一区二区a毛片,精品视频一区二区三区,国产在线三区http://www.aygfsteel.com/Todd/category/44805.htmlzh-cnThu, 10 Jun 2010 06:25:44 GMTThu, 10 Jun 2010 06:25:44 GMT60如何(g)SQL注入和CSSd漏洞http://www.aygfsteel.com/Todd/archive/2010/06/09/323154.htmlToddToddWed, 09 Jun 2010 06:50:00 GMThttp://www.aygfsteel.com/Todd/archive/2010/06/09/323154.htmlhttp://www.aygfsteel.com/Todd/comments/323154.htmlhttp://www.aygfsteel.com/Todd/archive/2010/06/09/323154.html#Feedback0http://www.aygfsteel.com/Todd/comments/commentRss/323154.htmlhttp://www.aygfsteel.com/Todd/services/trackbacks/323154.html

http://www.symantec.com/connect/articles/detection-sql-injection-and-cross-site-scripting-attacks

在这两年中,安全专家应该对网l应用层的攻?yn)L加重视。因为无Z有多强壮的防 火墙规则讄或者非常勤于补漏的修补机制Q如果你的网l应用程序开发者没有遵循安全代码进行开发,d者将通过80端口q入你的pȝ。广泛被使用的两个主 要攻?yn)L术是SQL注入[ref1]和CSS[ref2]d。SQL注入是指Q通过互联|的输入区域Q插入SQL meta-charactersQ特D字W? 代表一些数据)(j)和指令,操纵执行后端的SQL查询的技术。这些攻M要针对其他组l的WEB服务器。CSSd通过在URL里插入script标签Q然? 诱导信Q它们的用L(fng)d们,保恶意Javascript代码在受害h的机器上q行。这些攻d用了(jin)用户和服务器之间的信dp,事实上服务器没有对输 入、输?gu)行检,从而未拒绝javascript代码?/p>

q篇文章讨论SQL注入和CSSd漏洞的检技术。网上已l有很多关于q两U基于WEBd的讨论,比如如何实施dQ他们的影响Q怎样更好的编 制和设计E序防止q些d?然? 对如何检这些攻dƈ没有_的讨论。我们采用流行的开源的IDS Snort[ref 3],l徏Ҏ(gu)?hu)(g)这些攻ȝ规则的正则表辑ּ。附带,Snort默认规则讑֮包含(g)CSS的方法,但是q些Ҏ(gu)被避开(g)。比如大多通过hexq制~? ??3C%73%63%72%69%70% 74%3E代替<script>避开(g)?/p>

依赖level of paranoial织的能力,我们已经~写?jin)多U检相同攻ȝ规则。如果你希望(g)各U可能的SQL注入dQ那么你需要简单的留意M现行的SQL meta-charactersQ如单引P分号和双重破折号。同L(fng)一个极端检CSSd的方法,只要单地提防HTML标记的角括号。但q样?x)检? 出很多错误。ؓ(f)?jin)避免这些,q些规则需要修改它检更_? 当仍然不能避免错误?/p>

在Snort规则中用pcre(Perl Compatible Regular Expressions)[ref4]关键字,每个规则可以带或不带其他规则动作。这些规则也可以被公用Y件如grep(文档搜烦(ch)工具)使用Q来审阅|络 服务器日志?但是,需要警惕的是,用户的输入只有当以GET提交hӞW(xu)EB服务器才?x)记录日?如果是以POST提交的请求在日记中是不会(x)记录的?/p>

2. SQL注入的正则表C式

? 你ؓ(f)SQL注入d选择正则表示式的时候,重点要记住攻击者可以通过提交表单q行SQL注入Q也可以通过Cookie区域。你的输入检逻辑应该考虑用户 l织的各cd输入(比如表单或Cookie信息)。ƈ且如果你发现许多警告来自一个规则,L(fng)意单引号或者是分号Q也怺字符是你的Web应用E序创造的 合法的在CookieS中的输入。因? (zhn)需要根据你的特D的WEB应用E序评估每个规则?/p>

依照前面提到Q一个琐l的(g)SQL入d的正则表辑ּ要留意SQLҎ(gu)的meta-characters 譬如单引?’)双重扩则?--),Z(jin)查出q些字符和他们hex{值数, 以下正则表达式适用:

2.1 (g)SQL meta-characters的正则表辑ּ

/(\%27)|(’)|(--)|(\%23)|(#)/ix

解释:

?们首先检查单引号{值的hexQ单引号本n或者双重扩折号。这些是MS SQL Server或Oracle的字W? 表示后边的ؓ(f)评论, 随后的都被忽略?另外Q如果你使用MySQL,你需要留?’#’和它{值的hex的出现。注意我们不需要检查双重破折号{值的hex, 因ؓ(f)q不是HTML meta-character, 览器不?x)进行编码?q且, 如果d者设法手工修改双重破折号为它的hex?2D(使用代理像Achilles[ref 5]), SQL注入失败?
加入上述正则表达式的新的Snort规则如下:

alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:"SQL Injection - Paranoid"; flow:to_server,established;uricontent:".pl";pcre:"/(\%27)|(’)|(--)|(%23)|(#)/i"; classtype:Web-application-attack; sid:9099; rev:5;)

在本讨Z, uricontent关键字的gؓ(f)".pl ", 因ؓ(f)在我们的试环境? CGI E序是用Perl写的。uricontent关键字的值取决于(zhn)的Ҏ(gu)应用, q个g许是".php ", ? .asp ", ? .jsp ", {?从这点考虑, 我们不显C对应的Snort 规则, 但是我们?x)给出创造这些规则的正则表达式? 通过q些正则表达式你可以很简单的创造很多的Snort规则.在前面的正则表达式里, 我们(g)双重破折号是因为:(x)即便没有单引L(fng)存在那里也可能是SQL入点[ref 6]?例如, SQL查询条目只包含数|如下:

select value1, value2, num_value3 from database
where num_value3=some_user_supplied_number

q种情况Q攻击者可以执行额外的SQL查询, C提交如下输入:

3; insert values into some_other_table

最? pcre的修饰符’ i’ ?#8217; x ’ 是用于分别匹配大写和忽略空白处的? 上面的规则也可以另外扩展来检查分L(fng)存在。然而,分号很可以是正常HTTP应答的一部分。ؓ(f)?jin)减这U错误,也是Z(jin)M正常的单引号和双重扩折号的出 玎ͼ上面的规则应该被修改成先(g)=L(fng)存。用戯入会(x)响应一个GET或POSThQ一般输入提交如下:(x)

username=some_user_supplied_value&password=some_user_supplied_value

因此, SQL 注入试导致用L(fng)输入出现在a = h它等效的hexg后?/p>

2.2 修正(g)SQL meta-characters的正则表辑ּ

/((\%3D)|(=))[^ ]*((\%27)|(’)|(--)|(\%3B)|(:))/i

解释:

q个规则首先留意 = h它的hex?%3D)Q然后考虑零个或多个除换行W以外的L字符Q最后检单引号Q双重破折号或分受?/p>

典型的SQL注入?x)尝试围l单引号的用途操作原来的查询Q以便得到有用的价倹{讨个攻M般?’or’1’=’1字符? 但是, q个串的侦查很容易被逃避Q譬如用1’or2>1 --. 然而唯一恒定的部分是最初的字符的|跟随一单引P再加’or’。随后的布尔逻辑可能在一定范围上变化Q可以是普通样式也可能是非常复杂的。这些攻d 以相当精被侦测Q通过以下的正则表辑ּ?.3章节讲解?/p>

2.3 典型?SQL 注入d的正则表辑ּ

/w*((\%27)|(’))((\%6F)|o|(\%4F))((\%72)|r|(\%52))/ix

解释:
w* - 零个或多个字W或者下划线?
(\%27)|’ - 单引h它的hex{倹{?
(\%6 F)|o|(\%4 F))((\%72)|r|-(\%52) Q?#8216;or’的大写以及(qing)它的hex{倹{?/p>

union’SQL 查询在SQL注入各种数据库中d中同h很常见的。如果前面的正则表达式仅仅检单引号或则其他的SQL meta characters Q会(x)造成很多的错误存在。你应该q一步修Ҏ(gu)询,(g)单引号和关键字‘union’。这同样可以q一步扩展其他的SQL关键字,?#8217;select’, ’insert’, ’update’, ’delete’, {等?/p>

2.4 (g)SQL注入QUNION查询关键字的正则表达?/strong>

/((\%27)|(’))union/ix

(\%27)|(’) - 单引号和它的hex{?
union - union关键?/p>

可以同样为其他SQL查询定制表达式,?>select, insert, update, delete, drop, {等.

如果Q到q个阶段Q攻击者已l发现web应用E序存在SQL注入漏洞Q他尝试利用它。如果他认识到后端服务器式MS SQL serverQ他一般会(x)试q行一些危险的储存和扩展储存过E。这些过E一般以‘sp’?#8216;xp’字母开头。典型的Q他可能试q行 ‘xp_cmdshell’扩展储存q程Q通过SQL Server执行W(xu)indows 命o(h)Q。SQL服务器的SA权限有执行这些命令的权限。同样他们可以通过xp_regread, xp_regwrite{储存过E修Ҏ(gu)册表?/p>

2.5 (g)MS SQL Server SQL注入d的正则表辑ּ

/exec(s|+)+(s|x)pw+/ix

解释:
exec - h执行储存或扩展储存过E的关键?
(s|+)+ - 一个或多个的空白或它们的http{值编?
(s|x) p- ‘sp’?#8216;xp’字母用来辨认储存或扩展储存过E?
w+ - 一个或多个字符或下划线来匹配过E的名称

3. 跨站脚本(CSS)的正则表辑ּ

当发动CSSd或检一个网站漏z的时? d者可能首先ɽ单的HTML标签?lt;b>(_体),<i>(斜体)?lt;u>(下划U?Q或者他可能试单的 script标签?lt;script>alert("OK")</script>. 因ؓ(f)大多数出版物和网l传播的(g)网站是否有css漏洞都拿q个作ؓ(f)例子。这些尝试都可以很简单的被检出来? 然而,高明点的d者可能用它的hex值替换整个字W串。这?lt;script>标签?x)?3C%73%63%72%69%70%74%3E? 现? 另一斚wQ攻击者可能用web代理服务器像Achilles?x)自动{换一些特D字W如<换成%3C?gt;换成%3E.q样d发生ӞURL 中通常以hex{g替角括号?/p>

下列正则表达式将(g)Q何文本中包含的html?lt;?gt;。它?yu)捉住试图?lt; b>?lt;u>、或<script>。这正则表达式应该忽略大写。我们需要同时检角括号和它的hex{?% 3C|<)。检hexq制转化的整个字W串Q我们必L用戯入的数字?P即用[a-z0-9%] 。这可能?x)导致一些错误出玎ͼ不是大部分会(x)(g)到真实d的?/p>

3.1 一?CSS d的正则表辑ּ

/((\%3C)|<)((\%2F)|/)*[a-z0-9\%]+((\%3E)|>)/ix

解释:
((\%3C)|<) Q检?lt;和它hex{?
((\%2F)|/)*Q结束标{?或它?hex{?
[a-z0-9\%]+ Q检查标{N的字母或它hex{?
((\%3E)|>) Q检?gt;或它的hex{?/p>

Snort 规则:
alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:"NII Cross-site scripting attempt"; flow:to_server,established; pcre:"/((\%3C)|<)((\%2F)|/)*[a-z0-9\%]+((\%3E)|>)/i"; classtype:Web-application-attack; sid:9000; rev:5;)

跨站脚本同样可以使用<img src=>技术。现行默认的snort规则可以被轻易避开?/p>

3.2章节提供?jin)防止这U技术的Ҏ(gu)?/strong>

3.2 "<img src" CSS d正则表达?/p>

/((\%3C)|<)((\%69)|i|(\%49))((\%6D)|m|(\%4D))((\%67)|g|(\%47))[^ ]+((\%3E)|>)/I

解释:
(\%3 C)|<) -<或它的hex{?
(\%69)|i|(\%49))((\%6D)|m|(\%4D))((\%67)|g|(\%47) -’img’字母或它的大写hex{值的变化l合
[^ ]+ -除了(jin)换行W以外的M跟随<img的字W?
(\%3E)|>) ->或它的hex{?/p>

3.3 CSS d的极端的正则表达?/p>

/((\%3C)|<)[^ ]+((\%3E)|>)/I

解释:

q个规则单寻?lt;+除换行符外的M字符+>。由于你的web服务器和web应用E序的构Ӟq个规则可能产生一些错误。但它能保证 捉住MCCS或者类似CSS的攻凅R?/p>

ȝ:

? q篇文章中,我们提出?jin)不同种cȝ正则表达式规则来(g)SQL注入和跨站脚本攻凅R有些规则简单而极端,一个潜在的d都将提高警惕。但q些极端的规则可 能导致一些主动的错误。考虑到这点,我们修改?jin)这些简单的规则Q利用了(jin)另外的样式,他们可以(g)查的更准些。在q些|络应用成的d(g)中Q我们推荐将q? 些作试你I(yng)DS或日志分析方法的L(fng)。再l过几次修改后,在你Ҏ(gu)常网交易部分的非恶意应答q行评估以后Q你应该可以准备的检那些攻M(jin)?strong>

q篇是翻译老外的文章,css 跨站d只需qo(h)掉html括号即可,擦,又被专家们忽(zhn)了(jin)Q网上盛传的

完整的XSS wrom安全(g)实例示范,W一ơ就把标记对都过滤了(jin)Q下面竟然还用标记测试,啥逻辑Q我只想知道是怎么成功的,搞笑Q误?/p>



Todd 2010-06-09 14:50 发表评论
]]>
矛与盄较量Q?Q——奇妙的Base64~码http://www.aygfsteel.com/Todd/archive/2010/05/20/321432.htmlToddToddWed, 19 May 2010 17:48:00 GMThttp://www.aygfsteel.com/Todd/archive/2010/05/20/321432.htmlhttp://www.aygfsteel.com/Todd/comments/321432.htmlhttp://www.aygfsteel.com/Todd/archive/2010/05/20/321432.html#Feedback0http://www.aygfsteel.com/Todd/comments/commentRss/321432.htmlhttp://www.aygfsteel.com/Todd/services/trackbacks/321432.html阅读全文

Todd 2010-05-20 01:48 发表评论
]]>
矛与盄较量Q?Q——CRC实践?/title><link>http://www.aygfsteel.com/Todd/archive/2010/05/20/321431.html</link><dc:creator>Todd</dc:creator><author>Todd</author><pubDate>Wed, 19 May 2010 17:47:00 GMT</pubDate><guid>http://www.aygfsteel.com/Todd/archive/2010/05/20/321431.html</guid><wfw:comment>http://www.aygfsteel.com/Todd/comments/321431.html</wfw:comment><comments>http://www.aygfsteel.com/Todd/archive/2010/05/20/321431.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/Todd/comments/commentRss/321431.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/Todd/services/trackbacks/321431.html</trackback:ping><description><![CDATA[<a >下蝲本节例子E序</a> (13.4 KB)<br /> <strong>Q特别感谢汇~高?<font color="red">dREAMtHEATER</font> Ҏ(gu)的代码作Z(jin)相当好的优化Q请参观他的<a target="_blank">主页</a>Q?/strong><br /> <br /> 上一节里我们介绍?jin)CRC-32的实现原理,可是原理不能当饭吃吧Q下面让我们来看看CRC是怎么应用到文件保护上?#8230;…<br /> <br /> Q由于本文涉?qing)到的源代码比较多,so请各位读者自行下载代码进行分析)(j)<br /> <br /> ? 《原理篇》里面,我们已经知道Q通过对一个字W串q行CRC-32转换Q最后可以得C?个字节长的CRC-32|而且无论该字W串有多长,最l生? 的CRC-32值都肯定?个字节长。这q?jin)我们一个启C:(x)是否能够在一个文件的某个地方储存q个CRC-32|然后在文件运行的时候,再读取这? CRC-32|q行比较Q?br /> <br /> {案是肯定的。让我们先来看看PE文g的结构:(x)Q什么?你不懂PE文gl构Q!?#8230;…先去扄资料看看吧,到处都有的哦Q?br /> <br /> ? PE的可选映像头QIMAGE_OPTIONAL_HEADERQ里面,有一个保留字D:(x)Win32VersionQ根据MSDN的资料,它的g般是 0Q而且它的长度?个DWORD。呵呵,你是不是已经惛_什么了(jin)呢?对了(jin)Q它的长度和我们要储存的CRC-32正好是相{的Q而且它的值是不变的,一? ?Q别问我Z么啊Q我也不知道Q。这q我们提供?jin)一个储存CRC-32I间的可能,而实际上Q有很多Win32病毒也是利用q个 Win32Verion保留字段来储存它们的感染标志的?br /> <br /> 好了(jin)Q明了(jin)目标Q我们来看看具体应该怎么实现Q?br /> <br /> 1、先写一? W三方的E序Q我假设它叫“AddCRC32ToFile.exe”。我们可以利用这个程序,打开一个文Ӟ假设q个文g叫做 “CRC32_Test.exe”Q然?#8220;AddCRC32ToFile.exe”׃(x)计算?#8220;CRC32_Test.exe”的CRC-32|q把q? 个CRC-32值写?#8220;CRC32_Test.exe”的Win32Version处。(其实q步要到最后才做的Q?br /> <br /> 2、写好需要进行保? 的程序,在这里我假设它叫?#8220;CRC32_Test.exe”Q记住一定要在这个程序里面加入CRC-32的校验模块。这个校验模块的工作q程是这? 的:(x)a、先d自n文g的所有内容,储存在一个字W串中,然后把这个字W串的Win32Version处的4个字节改??Q再把字W串q行CRC- 32转换Q这时我们就得到?jin)一?#8220;原始”文g的CRC-32|b、读取自w文件的Win32Version处的|q个值是我们通过 “AddCRC32ToFile.exe”写进ȝ。最后我们把步骤a和b中得到的两个CRC-32D行比较,如果相等的话Q说明文件没有被修改q;? 之就说明文g已经被修改了(jin)?br /> <br /> 很复杂是吧?其实好好想一惻I没啥困难的。关键是要按照以下步骤进行:(x)<br /> <br /> 1、一定要先在 “CRC32_Test.exe”里面写好所有的模块Q然后才?#8220;AddCRC32ToFile.exe”?#8220;CRC32_Test.exe”的CRC- 32值写?#8220;CRC32_Test.exe”的Win32Version处,否则最后得到的l果肯定是不正确的。顺序一定不能搞错!Q!<br /> <br /> 2、今后一旦修改了(jin)“CRC32_Test.exe”的内容(比如重新~译?jin)一ơ)(j)Q就一定要再用“AddCRC32ToFile.exe”重新把CRC-32值写?#8220;CRC32_Test.exe”中去Q否则结果也是会(x)不正的?br /> <br /> 其实Ҏ(gu)不止q一U,q有以下的几U是可行的:(x)<br /> 1、把CRC-32的值写入一个单独的DLL文g中(或者别的什么ؕ七八p的地方Q随你的便)(j)Q然后在q行的时候读取DLL文g中储存好的CRC-32|q行比较?br /> 2、把CRC-32的D加到.exe文g的最后,在运行的时候读取这最后的4个字节的内容Q进行比较。不q我觉得q样做不太好Q呵呵,因ؓ(f)增加?jin)文件的长度?br /> ……<br /> <br /> 我的Ҏ(gu)的缺点分析:(x)<br /> CRC-32的值其实可以由Cracker自行计算得出后,重新写入到Win32Version处。这L(fng)话,我们做的工作岂不是没有意义了(jin)Q?br /> ? 实解决的Ҏ(gu)q是有的Q我们可以在计算CRC-32g前,寚w要进行{换的字符串加Ҏ(gu)脚,例如对这个字W串q行UM、xor{操作,或者把自己的生? {信息加入到字符串中Q随你的便什么都行,M不是单纯的文件的内容p?jin),然后在最后比较的时候,也用同样的方法反计算出CRC-32倹{这样得到的 CRC-32׃是由文g的内容计出来的Q相信对Cracker的阻力也?x)加大不?br /> <br /> ȝQ?br /> 应用CRC原理到文件的自校验保护中Q是一U很灉|的手D,可用的方法有很多U。本文只是抛砖引玉,希望高手能给出更好的解决Ҏ(gu)Qƈ请发信到<a href="mailto:lcother@163.net?subject=%E8%80%81%E7%BD%97%EF%BC%8C%E6%9C%89%E5%85%B3CRC-32%E7%9A%84%E9%97%AE%E9%A2%98%E6%83%B3%E8%B7%9F%E4%BD%A0%E7%A0%94%E7%A9%B6%EF%BC%81" title="共同研究Q?>lcother@163.net</a>Q我们共同研IӞ多谢Q!Q? <img src ="http://www.aygfsteel.com/Todd/aggbug/321431.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/Todd/" target="_blank">Todd</a> 2010-05-20 01:47 <a href="http://www.aygfsteel.com/Todd/archive/2010/05/20/321431.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>矛与盄较量Q?Q——CRC原理?/title><link>http://www.aygfsteel.com/Todd/archive/2010/05/20/321430.html</link><dc:creator>Todd</dc:creator><author>Todd</author><pubDate>Wed, 19 May 2010 17:45:00 GMT</pubDate><guid>http://www.aygfsteel.com/Todd/archive/2010/05/20/321430.html</guid><wfw:comment>http://www.aygfsteel.com/Todd/comments/321430.html</wfw:comment><comments>http://www.aygfsteel.com/Todd/archive/2010/05/20/321430.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/Todd/comments/commentRss/321430.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/Todd/services/trackbacks/321430.html</trackback:ping><description><![CDATA[<a >下蝲本节例子E序</a> (4.29 KB)<br /> <strong>Q特别感谢汇~高?<font color="red">dREAMtHEATER</font> Ҏ(gu)的代码作Z(jin)相当好的优化Q请参观他的<a target="_blank">主页</a>Q?/strong><br /> <br /> 上一节我们介l了(jin)花指令,不过花指令毕竟是一U很单的东西Q基本上入了(jin)门的Cracker都可以对付得?jin)。所以,我们很有必要l自q软g加上更好的保护。CRC校验是其中的一U不错的Ҏ(gu)?br /> <br /> CRC 是什么东西呢Q其实我们大安不应该会(x)对它陌生Q回忆一下?你用qRAR和ZIP{压~Y件吗Q它们是不是常常?x)给你一个恼人的“CRC校验错误”信息 呢?我想你应该明白了(jin)吧,CRC是块数据的计算|它的全称?#8220;Cyclic Redundancy Check”Q中文名?#8220;循环冗余?#8221;Q?#8220;CRC校验”是“循环冗余校验”。(哇,真拗口,希望大家不要当我是唐僧,呵呵。^_^Q?br /> <br /> CRC 有什么用呢?它的应用范围很广泛,最常见的就是在|络传输中进行信息的校对。其实我们大可以把它应用到Y件保护中去,因ؓ(f)它的计算是非帔R帔R怸格的? 严格C么程度呢Q你的程序只要被改动?jin)一个字节(甚至只是大小写的改动Q,它的值就?x)跟原来的不同。HohoQ是不是很厉宛_Q所以只要给你的“?#8221;E? 序计好CRC|储存在某个地方,然后在程序中随机地再Ҏ(gu)件进行CRC校验Q接着跟第一ơ生成ƈ保存好的CRCD行比较,如果相等的话p明你的程 序没有被修改/破解q,如果不等的话Q那么很可能你的E序遭到?jin)病毒的感染Q或者被Cracker?6q制工具暴力破解q了(jin)?br /> <br /> 废话说完?jin),我们先来看看CRC的原理?br /> Q由于CRC实现h有一定的隑ֺQ所以具体怎样用它来保护文Ӟ留待下一节再讌Ӏ)(j)<br /> <br /> 首先看两个式子:(x)<br /> 式一Q? / 3 = 3          Q余?= 0Q?br /> 式二Q?9 + 2 ) / 3 = 3   Q余?= 2Q?br /> <br /> 在小学里我们q道,除法q算是被减数重复地减去除数Xơ,然后留下余数?br /> 所以上面的两个式子可以用二q制计算为:(x)Q什么?你不?x)二q制计算Q我倒~~~Q?br /> <br /> 式一Q?br /> 1001        --> 9<br /> 0011    -   --> 3<br /> ---------<br /> 0110        --> 6<br /> 0011    -   --> 3<br /> ---------<br /> 0011        --> 3<br /> 0011    -   --> 3<br /> ---------<br /> 0000        --> 0Q余?br /> 一共减?ơ,所以商?Q而最后一ơ减出来的结果是0Q所以余Cؓ(f)0<br /> <br /> 式二Q?br /> 1011        --> 11<br /> 0011    -   --> 3<br /> ---------<br /> 1000        --> 8<br /> 0011    -   --> 3<br /> ---------<br /> 0101        --> 5<br /> 0011    -   --> 3<br /> ---------<br /> 0010        --> 2,余数<br /> 一共减?ơ,所以商?Q而最后一ơ减出来的结果是2Q所以余Cؓ(f)2<br /> <br /> 看明白了(jin)吧?很好Qlet’s go on!<br /> <br /> 二进制减法运的规则是,如果遇到0-1的情况,那么要从高(sh)?Q就变成?10+0)-1=1<br /> CRCq算有什么不同呢Q让我们看下面的例子Q?br /> <br /> q次用式?0 / 9Q不q请读者注意最后的余数Q?br /> <br /> 11110        --> 30<br /> 1001    -    --> 9<br /> ---------<br />  1100        --> 12    Q很奇怪吧Qؓ(f)什么不?1呢?Q?br />  1001   -    --> 9<br />  --------<br />   101        --> 5Q余?--> the CRC!<br /> <br /> q个式子的计过E是不是很奇怪呢Q它不是直接减的Q而是用XOR的方式来q算Q程序员应该都很熟?zhn)XOR吧)(j)Q最后得C个余数?br /> <br /> 对啦Q这个就是CRC的运方法,明白?jin)吗QCRC的本质是q行XORq算Q运的q程我们不用它Q因过E对最后的l果没有意义Q我们真正感兴趣的只是最l得到的余数Q这个余数就是CRC倹{?br /> <br /> q行一个CRCq算我们需要选择一个除敎ͼq个除数我们叫它?#8220;poly”Q宽度W是最高(sh)的位|,所以我刚才丄例子中的除数9Q这个poly 1001的W?Q而不?Q注意最高(sh)L1。(别问Z么,q个是规定)(j)<br /> <br /> 如果我们惌一个位串的CRC码,我们想确定每一个位都被处理q,因此Q我们要在目标位串后面加上W?位。现在让我们Ҏ(gu)CRC的规范来改写一下上面的例子Q?br /> <br /> Poly                    =    1001Q宽度W = 3<br /> 位串Bitstring           =    11110<br /> Bitstring + W zeroes    =    11110 + 000 = 11110000<br /> <br /> 11110000<br /> 1001||||    -<br /> -------------<br />  1100|||<br />  1001|||    -<br />  ------------<br />   1010||<br />   1001||    -<br />   -----------<br />    0110|<br />    0000|    -<br />    ----------<br />     1100<br />     1001    -<br />     ---------<br />      101        --> 5Q余?--> the CRC!<br /> <br /> q有两点重要声明如下Q?br /> 1、只有当Bitstring的最高(sh)?Q我们才它与polyq行XORq算Q否则我们只是将Bitstring左移一位?br /> 2、XORq算的结果就是被操作位串Bitstring与poly的低W位进行XORq算Q因为最高(sh)Mؓ(f)0?br /> <br /> 呵呵Q是不是有点头晕脑胀的感觉了(jin)Q看不懂的话Q再从头看一遍,其实是很好理解的。(是一个XORq算嘛!Q?br /> <br /> <br /> 好啦Q原理介l到q里Q下面我讲讲具体怎么~程?br /> <br /> ׃速度的关p,CRC的实C要是通过查表法,对于CRC-16和CRC-32Q各自有一个现成的表,大家可以直接引入到程序中使用。(׃q两个表太长Q在q里不列出来?jin),误者自行在|络上查找,很容易找到的。)(j)<br /> <br /> 如果我们没有q个表怎么办呢Q或者你跟我一P懒得自己输入Q不用急,我们可以“自己动手Q丰衣?#8221;?br /> 你可能会(x)_(d)自己~程来生成这个表Q会(x)不会(x)太慢?jin)?其实大可不必担?j)Q因为我们是在汇~代码的U别q行q算的,而这个表只有区区256个双字,Ҏ(gu)影响不了(jin)速度?br /> <br /> q个表的C语言描述如下Q?br /> <br /> <table bgcolor="#fbedbb" border="0" cellpadding="0" cellspacing="0"> <tbody> <tr> <td><a name="L1"><font color="#ff0000">for</font> <font color="#ff00ff">(</font>i <font color="#3080ca">=</font> <font color="#802000">0</font><font color="#9932cd"><strong>;</strong></font> i <font color="#3080ca"><</font> <font color="#802000">256</font><font color="#9932cd"><strong>;</strong></font> i<font color="#3080ca">++</font><font color="#ff00ff">)</font><br /> </a><a name="L2"><font color="#db3098">{</font><br /> </a><a name="L3">    crc <font color="#3080ca">=</font> i<font color="#9932cd"><strong>;</strong></font><br /> </a><a name="L4">    <font color="#ff0000">for</font> <font color="#ff00ff">(</font>j <font color="#3080ca">=</font> <font color="#802000">0</font><font color="#9932cd"><strong>;</strong></font> j <font color="#3080ca"><</font> <font color="#802000">8</font><font color="#9932cd"><strong>;</strong></font> j<font color="#3080ca">++</font><font color="#ff00ff">)</font><br /> </a><a name="L5">    <font color="#db3098">{</font><br /> </a><a name="L6">        <font color="#ff0000">if</font> <font color="#ff00ff">(</font>crc <font color="#3080ca">&</font> <font color="#802000">1</font><font color="#ff00ff">)</font><br /> </a><a name="L7">            crc <font color="#3080ca">=</font> <font color="#ff00ff">(</font>crc <font color="#3080ca">>></font> <font color="#802000">1</font><font color="#ff00ff">)</font> <font color="#3080ca">^</font> <font color="#802000">0xEDB88320</font><font color="#9932cd"><strong>;</strong></font><br /> </a><a name="L8">        <font color="#ff0000">else</font><br /> </a><a name="L9">            crc <font color="#3080ca">>>=</font> <font color="#802000">1</font><font color="#9932cd"><strong>;</strong></font><br /> </a><a name="L10">    <font color="#db3098">}</font><br /> </a><a name="L11">    crc32tbl<font color="#871f78">[</font>i<font color="#871f78">]</font> <font color="#3080ca">=</font> crc<font color="#9932cd"><strong>;</strong></font><br /> </a><a name="L12"><font color="#db3098">}</font></a></td> </tr> </tbody> </table> <br /> 生成表之后,可以进行运了(jin)?br /> 我们的算法如下:(x)<br /> 1、将寄存器向双Ud一个字节?br /> 2、将刚移出的那个字节与我们的字符串中的新字节q行XORq算Q得Z个指向Dtable[0..255]的烦(ch)引?br /> 3、将索引所指的表g寄存器做XORq算?br /> 4、如果数据没有全部处理完Q则跛_步骤1?br /> <br /> q个法的C语言描述如下Q?br /> <br /> <table bgcolor="#fbedbb" border="0" cellpadding="0" cellspacing="0"> <tbody> <tr> <td><a name="L1">    temp <font color="#3080ca">=</font> <font color="#ff00ff">(</font>oldcrc <font color="#3080ca">^</font> abyte<font color="#ff00ff">)</font> <font color="#3080ca">&</font> <font color="#802000">0x000000FF</font><font color="#9932cd"><strong>;</strong></font><br /> </a><a name="L2">    crc  <font color="#3080ca">=</font> <font color="#ff00ff">(</font><font color="#ff00ff">(</font> oldcrc <font color="#3080ca">>></font> <font color="#802000">8</font><font color="#ff00ff">)</font> <font color="#3080ca">&</font> <font color="#802000">0x00FFFFFF</font><font color="#ff00ff">)</font> <font color="#3080ca">^</font> crc32tbl<font color="#871f78">[</font>temp<font color="#871f78">]</font><font color="#9932cd"><strong>;</strong></font><br /> </a><a name="L3">    <font color="#ff0000">return</font> crc<font color="#9932cd"><strong>;</strong></font></a></td> </tr> </tbody> </table> <br /> 好啦Q所有的东东都说完啦Q最后献上一个完整的Win32Asm例子Q请读者仔l研I吧Q?br /> Q汇~方面的CRC-32资料极少啊,我个Z面给出的是很宝贵的资料。)(j)<br /> <br /> <br /> <table bgcolor="#fbedbb" border="0" cellpadding="0" cellspacing="0"> <tbody> <tr> <td><a name="L1"><font color="#238e23">;****************************************************</font><br /> </a><a name="L2"><font color="#238e23">;E序名称Q演CCRC32原理</font><br /> </a><a name="L3"><font color="#238e23">;作者:(x)|聪</font><br /> </a><a name="L4"><font color="#238e23">;日期Q?002-8-24</font><br /> </a><a name="L5"><font color="#238e23">;出处Qhttp://laoluoc.yeah.netQ老罗的缤U天圎ͼ(j)</font><br /> </a><a name="L6"><font color="#238e23">;注意事项Q如Ʋ{载,请保持本E序的完_(d)q注明:(x)转蝲?#8220;老罗的缤U天?#8221;Qhttp://laoluoc.yeah.netQ?/font><br /> </a><a name="L7"><font color="#238e23">;</font><br /> </a><a name="L8"><font color="#238e23">;特别感谢Win32ASM高手—?dREAMtHEATER 为我的代码作?jin)相当好的优化?/font><br /> </a><a name="L9"><font color="#238e23">;请各位前?http://NoteXPad.yeah.net 下蝲他的y?#8220;cool C?#8221;—?NoteXPad 来试用!Q?00% Win32ASM ~写Q?/font><br /> </a><a name="L10"><font color="#238e23">;</font><br /> </a><a name="L11"><font color="#238e23">;****************************************************</font><br /> </a><a name="L12"><br /> </a><a name="L13"><font color="#9932cd"><strong>.</strong></font><font color="#802000">386</font><br /> </a><a name="L14"><font color="#9932cd"><strong>.</strong></font><font color="#ff0000">model</font> <font color="#ff0000">flat</font><font color="#9932cd"><strong>,</strong></font> <font color="#ff0000">stdcall</font><br /> </a><a name="L15"><font color="#ff0000">option</font> <font color="#ff0000">casemap</font><font color="#3080ca">:</font>none<br /> </a><a name="L16"><br /> </a><a name="L17"><font color="#ff8000">include</font> windows.inc<br /> </a><a name="L18"><font color="#ff8000">include</font> kernel32.inc<br /> </a><a name="L19"><font color="#ff8000">include</font> user32.inc<br /> </a><a name="L20"><font color="#ff8000">includelib</font> kernel32.lib<br /> </a><a name="L21"><font color="#ff8000">includelib</font> user32.lib<br /> </a><a name="L22"><br /> </a><a name="L23">WndProc            <font color="#ff0000">proto</font> <font color="#3080ca">:</font><font color="#ff0000">DWORD</font><font color="#9932cd"><strong>,</strong></font> <font color="#3080ca">:</font><font color="#ff0000">DWORD</font><font color="#9932cd"><strong>,</strong></font> <font color="#3080ca">:</font><font color="#ff0000">DWORD</font><font color="#9932cd"><strong>,</strong></font> <font color="#3080ca">:</font><font color="#ff0000">DWORD</font><br /> </a><a name="L24">init_crc32table    <font color="#ff0000">proto</font><br /> </a><a name="L25">arraycrc32         <font color="#ff0000">proto</font><br /> </a><a name="L26"><br /> </a><a name="L27"><font color="#9932cd"><strong>.</strong></font><font color="#ff0000">const</font><br /> </a><a name="L28">IDC_BUTTON_OPEN        <font color="#ff0000">equ</font>    <font color="#802000">3000</font><br /> </a><a name="L29">IDC_EDIT_INPUT         <font color="#ff0000">equ</font>    <font color="#802000">3001</font><br /> </a><a name="L30"><br /> </a><a name="L31"><font color="#9932cd"><strong>.</strong></font><font color="#ff0000">data</font><br /> </a><a name="L32">szDlgName         <font color="#ff0000">db</font>    <font color="#0000ff">"lc_dialog"</font><font color="#9932cd"><strong>,</strong></font> <font color="#802000">0</font><br /> </a><a name="L33">szTitle           <font color="#ff0000">db</font>    <font color="#0000ff">"CRC demo by LC"</font><font color="#9932cd"><strong>,</strong></font> <font color="#802000">0</font><br /> </a><a name="L34">szTemplate        <font color="#ff0000">db</font>    <font color="#0000ff">"字符?""%s"" ?CRC32 值是Q?X"</font><font color="#9932cd"><strong>,</strong></font> <font color="#802000">0</font><br /> </a><a name="L35">crc32tbl          <font color="#ff0000">dd</font>    <font color="#802000">256</font> <font color="#ff0000">dup</font><font color="#ff00ff">(</font><font color="#802000">0</font><font color="#ff00ff">)</font>    <font color="#238e23">;CRC-32 table</font><br /> </a><a name="L36">szBuffer          <font color="#ff0000">db</font>    <font color="#802000">255</font> <font color="#ff0000">dup</font><font color="#ff00ff">(</font><font color="#802000">0</font><font color="#ff00ff">)</font><br /> </a><a name="L37"><br /> </a><a name="L38"><font color="#9932cd"><strong>.</strong></font><font color="#ff0000">data</font><font color="#3080ca">?</font><br /> </a><a name="L39">szText            <font color="#ff0000">db</font>    <font color="#802000">300</font> <font color="#ff0000">dup</font><font color="#ff00ff">(</font><font color="#3080ca">?</font><font color="#ff00ff">)</font><br /> </a><a name="L40"><br /> </a><a name="L41"><font color="#9932cd"><strong>.</strong></font><font color="#ff0000">code</font><br /> </a><a name="L42">main<font color="#3080ca">:</font><br /> </a><a name="L43">    <font color="#ff0000">invoke</font> GetModuleHandle<font color="#9932cd"><strong>,</strong></font> NULL<br /> </a><a name="L44">    <font color="#ff0000">invoke</font> DialogBoxParam<font color="#9932cd"><strong>,</strong></font> <font color="#ff0000">eax</font><font color="#9932cd"><strong>,</strong></font> <font color="#ff0000">offset</font> szDlgName<font color="#9932cd"><strong>,</strong></font> <font color="#802000">0</font><font color="#9932cd"><strong>,</strong></font> WndProc<font color="#9932cd"><strong>,</strong></font> <font color="#802000">0</font><br /> </a><a name="L45">    <font color="#ff0000">invoke</font> ExitProcess<font color="#9932cd"><strong>,</strong></font> <font color="#ff0000">eax</font><br /> </a><a name="L46"><br /> </a><a name="L47">WndProc <font color="#ff0000">proc</font> <font color="#ff0000">uses</font> <font color="#ff0000">ebx</font> hWnd<font color="#3080ca">:</font>HWND<font color="#9932cd"><strong>,</strong></font> uMsg<font color="#3080ca">:</font>UINT<font color="#9932cd"><strong>,</strong></font> wParam<font color="#3080ca">:</font>WPARAM<font color="#9932cd"><strong>,</strong></font> lParam<font color="#3080ca">:</font>LPARAM<br /> </a><a name="L48"><br /> </a><a name="L49">    <font color="#9932cd"><strong>.</strong></font><font color="#ff0000">if</font> uMsg <font color="#3080ca">=</font><font color="#3080ca">=</font> WM_CLOSE<br /> </a><a name="L50">        <font color="#ff0000">invoke</font> EndDialog<font color="#9932cd"><strong>,</strong></font> hWnd<font color="#9932cd"><strong>,</strong></font> <font color="#802000">0</font><br /> </a><a name="L51">        <br /> </a><a name="L52">    <font color="#9932cd"><strong>.</strong></font><font color="#ff0000">elseif</font> uMsg <font color="#3080ca">=</font><font color="#3080ca">=</font> WM_COMMAND<br /> </a><a name="L53">        <font color="#ff0000">mov</font> <font color="#ff0000">eax</font><font color="#9932cd"><strong>,</strong></font>wParam<br /> </a><a name="L54">        <font color="#ff0000">mov</font> <font color="#ff0000">edx</font><font color="#9932cd"><strong>,</strong></font><font color="#ff0000">eax</font><br /> </a><a name="L55">        <font color="#ff0000">shr</font> <font color="#ff0000">edx</font><font color="#9932cd"><strong>,</strong></font><font color="#802000">16</font><br /> </a><a name="L56">        <font color="#ff0000">movzx</font> <font color="#ff0000">eax</font><font color="#9932cd"><strong>,</strong></font> <font color="#ff0000">ax</font><br /> </a><a name="L57">        <font color="#9932cd"><strong>.</strong></font><font color="#ff0000">if</font> <font color="#ff0000">edx</font> <font color="#3080ca">=</font><font color="#3080ca">=</font> BN_CLICKED<br /> </a><a name="L58">            <font color="#9932cd"><strong>.</strong></font><font color="#ff0000">IF</font> <font color="#ff0000">eax</font> <font color="#3080ca">=</font><font color="#3080ca">=</font> IDCANCEL<br /> </a><a name="L59">                <font color="#ff0000">invoke</font> EndDialog<font color="#9932cd"><strong>,</strong></font> hWnd<font color="#9932cd"><strong>,</strong></font> NULL<br /> </a><a name="L60">            <font color="#9932cd"><strong>.</strong></font><font color="#ff0000">ELSEIF</font> <font color="#ff0000">eax</font> <font color="#3080ca">=</font><font color="#3080ca">=</font> IDC_BUTTON_OPEN <font color="#3080ca">|</font><font color="#3080ca">|</font> <font color="#ff0000">eax</font> <font color="#3080ca">=</font><font color="#3080ca">=</font> IDOK        <br /> </a><a name="L61">                <font color="#238e23">;******************************************</font><br /> </a><a name="L62">                <font color="#238e23">;关键代码开始:(x)Q当当当?#8230;…Q?/font><br /> </a><a name="L63">                <font color="#238e23">;******************************************</font><br /> </a><a name="L64">                <font color="#238e23">;取得用户输入的字W串Q?/font><br /> </a><a name="L65">                <font color="#ff0000">invoke</font> GetDlgItemText<font color="#9932cd"><strong>,</strong></font> hWnd<font color="#9932cd"><strong>,</strong></font> IDC_EDIT_INPUT<font color="#9932cd"><strong>,</strong></font> <font color="#ff0000">addr</font> szBuffer<font color="#9932cd"><strong>,</strong></font> <font color="#802000">255</font><br /> </a><a name="L66"><br /> </a><a name="L67">                <font color="#238e23">;初始化crc32tableQ?/font><br /> </a><a name="L68">                <font color="#ff0000">invoke</font> init_crc32table<br /> </a><a name="L69"><br /> </a><a name="L70">                <font color="#238e23">;下面赋值给寄存器ebxQ以便进行crc32转换Q?/font><br /> </a><a name="L71">                <font color="#238e23">;EBX是待转换的字W串的首地址Q?/font><br /> </a><a name="L72">                <font color="#ff0000">lea</font> <font color="#ff0000">ebx</font><font color="#9932cd"><strong>,</strong></font> szBuffer<br /> </a><a name="L73"><br /> </a><a name="L74">                <font color="#238e23">;q行crc32转换Q?/font><br /> </a><a name="L75">                <font color="#ff0000">invoke</font> arraycrc32<br /> </a><a name="L76"><br /> </a><a name="L77">                <font color="#238e23">;格式化输出:(x)</font><br /> </a><a name="L78">                <font color="#ff0000">invoke</font> wsprintf<font color="#9932cd"><strong>,</strong></font> <font color="#ff0000">addr</font> szText<font color="#9932cd"><strong>,</strong></font> <font color="#ff0000">addr</font> szTemplate<font color="#9932cd"><strong>,</strong></font> <font color="#ff0000">addr</font> szBuffer<font color="#9932cd"><strong>,</strong></font> <font color="#ff0000">eax</font><br /> </a><a name="L79"><br /> </a><a name="L80">                <font color="#238e23">;好啦Q让我们昄l果Q?/font><br /> </a><a name="L81">                <font color="#ff0000">invoke</font> MessageBox<font color="#9932cd"><strong>,</strong></font> hWnd<font color="#9932cd"><strong>,</strong></font> <font color="#ff0000">addr</font> szText<font color="#9932cd"><strong>,</strong></font> <font color="#ff0000">addr</font> szTitle<font color="#9932cd"><strong>,</strong></font> MB_OK<br /> </a><a name="L82">            <font color="#9932cd"><strong>.</strong></font><font color="#ff0000">ENDIF</font><br /> </a><a name="L83">        <font color="#9932cd"><strong>.</strong></font><font color="#ff0000">endif</font><br /> </a><a name="L84">    <font color="#9932cd"><strong>.</strong></font><font color="#ff0000">ELSE</font><br /> </a><a name="L85">        <font color="#ff0000">mov</font> <font color="#ff0000">eax</font><font color="#9932cd"><strong>,</strong></font>FALSE<br /> </a><a name="L86">        <font color="#ff0000">ret</font><br /> </a><a name="L87">    <font color="#9932cd"><strong>.</strong></font><font color="#ff0000">ENDIF</font><br /> </a><a name="L88">    <font color="#ff0000">mov</font> <font color="#ff0000">eax</font><font color="#9932cd"><strong>,</strong></font>TRUE<br /> </a><a name="L89">    <font color="#ff0000">ret</font><br /> </a><a name="L90">WndProc <font color="#ff0000">endp</font><br /> </a><a name="L91"><br /> </a><a name="L92"><font color="#238e23">;**********************************************************</font><br /> </a><a name="L93"><font color="#238e23">;函数功能Q生成CRC-32?/font><br /> </a><a name="L94"><font color="#238e23">;**********************************************************</font><br /> </a><a name="L95">init_crc32table    <font color="#ff0000">proc</font><br /> </a><a name="L96"><br /> </a><a name="L97">        <font color="#238e23">;如果用C语言来表C,应该如下Q?/font><br /> </a><a name="L98">        <font color="#238e23">;</font><br /> </a><a name="L99">        <font color="#238e23">;    for (i = 0; i < 256; i++)</font><br /> </a><a name="L100">        <font color="#238e23">;    {</font><br /> </a><a name="L101">        <font color="#238e23">;        crc = i;</font><br /> </a><a name="L102">        <font color="#238e23">;        for (j = 0; j < 8; j++)</font><br /> </a><a name="L103">        <font color="#238e23">;        {</font><br /> </a><a name="L104">        <font color="#238e23">;            if (crc & 1)</font><br /> </a><a name="L105">        <font color="#238e23">;                crc = (crc >> 1) ^ 0xEDB88320;</font><br /> </a><a name="L106">        <font color="#238e23">;            else</font><br /> </a><a name="L107">        <font color="#238e23">;                crc >>= 1;</font><br /> </a><a name="L108">        <font color="#238e23">;        }</font><br /> </a><a name="L109">        <font color="#238e23">;        crc32tbl[i] = crc;</font><br /> </a><a name="L110">        <font color="#238e23">;    }</font><br /> </a><a name="L111">        <font color="#238e23">;</font><br /> </a><a name="L112">        <font color="#238e23">;呵呵Q让我们把上面的语句Ҏ(gu)assembly的:(x)</font><br /> </a><a name="L113"><br /> </a><a name="L114">        <font color="#ff0000">mov</font>     <font color="#ff0000">ecx</font><font color="#9932cd"><strong>,</strong></font> <font color="#802000">256</font>        <font color="#238e23">; repeat for every DWORD in table</font><br /> </a><a name="L115">        <font color="#ff0000">mov</font>     <font color="#ff0000">edx</font><font color="#9932cd"><strong>,</strong></font> <font color="#802000">0EDB88320h</font><br /> </a><a name="L116"><font color="#802000">$BigLoop</font><font color="#3080ca">:</font><br /> </a><a name="L117">        <font color="#ff0000">lea</font>     <font color="#ff0000">eax</font><font color="#9932cd"><strong>,</strong></font> <font color="#871f78">[</font><font color="#ff0000">ecx</font><font color="#3080ca">-</font><font color="#802000">1</font><font color="#871f78">]</font><br /> </a><a name="L118">        <font color="#ff0000">push</font>    <font color="#ff0000">ecx</font><br /> </a><a name="L119">        <font color="#ff0000">mov</font>     <font color="#ff0000">ecx</font><font color="#9932cd"><strong>,</strong></font> <font color="#802000">8</font><br /> </a><a name="L120"><font color="#802000">$SmallLoop</font><font color="#3080ca">:</font><br /> </a><a name="L121">        <font color="#ff0000">shr</font>     <font color="#ff0000">eax</font><font color="#9932cd"><strong>,</strong></font> <font color="#802000">1</font><br /> </a><a name="L122">        <font color="#ff0000">jnc</font>     @F<br /> </a><a name="L123">        <font color="#ff0000">xor</font>     <font color="#ff0000">eax</font><font color="#9932cd"><strong>,</strong></font> <font color="#ff0000">edx</font><br /> </a><a name="L124">@@<font color="#3080ca">:</font><br /> </a><a name="L125">        <font color="#ff0000">dec</font>     <font color="#ff0000">ecx</font><br /> </a><a name="L126">        <font color="#ff0000">jne</font>     <font color="#802000">$SmallLoop</font><br /> </a><a name="L127">        <font color="#ff0000">pop</font>     <font color="#ff0000">ecx</font><br /> </a><a name="L128">        <font color="#ff0000">mov</font>     <font color="#871f78">[</font>crc32tbl<font color="#3080ca">+</font><font color="#ff0000">ecx</font><font color="#3080ca">*</font><font color="#802000">4</font><font color="#3080ca">-</font><font color="#802000">4</font><font color="#871f78">]</font><font color="#9932cd"><strong>,</strong></font> <font color="#ff0000">eax</font><br /> </a><a name="L129">        <font color="#ff0000">dec</font>     <font color="#ff0000">ecx</font><br /> </a><a name="L130">        <font color="#ff0000">jne</font>     <font color="#802000">$BigLoop</font><br /> </a><a name="L131"><br /> </a><a name="L132">        <font color="#ff0000">ret</font><br /> </a><a name="L133">init_crc32table      <font color="#ff0000">endp</font><br /> </a><a name="L134"><br /> </a><a name="L135"><br /> </a><a name="L136"><font color="#238e23">;**************************************************************</font><br /> </a><a name="L137"><font color="#238e23">;函数功能Q计CRC-32</font><br /> </a><a name="L138"><font color="#238e23">;**************************************************************</font><br /> </a><a name="L139">arraycrc32    <font color="#ff0000">proc</font><br /> </a><a name="L140"><br /> </a><a name="L141">        <font color="#238e23">;计算 CRC-32 Q我采用的是把整个字W串当作一个数l,然后把这个数l的首地址赋值给 EBXQ把数组的长度赋值给 ECXQ然后@环计,q回|计算出来?CRC-32 |(j)储存?EAX 中:(x)</font><br /> </a><a name="L142">        <font color="#238e23">;</font><br /> </a><a name="L143">        <font color="#238e23">; 参数Q?/font><br /> </a><a name="L144">        <font color="#238e23">;       EBX = address of first byte</font><br /> </a><a name="L145">        <font color="#238e23">; q回|(x)</font><br /> </a><a name="L146">        <font color="#238e23">;       EAX = CRC-32 of the entire array</font><br /> </a><a name="L147">        <font color="#238e23">;       EBX = ?</font><br /> </a><a name="L148">        <font color="#238e23">;       ECX = 0</font><br /> </a><a name="L149">        <font color="#238e23">;       EDX = ?</font><br /> </a><a name="L150"><br /> </a><a name="L151">        <font color="#ff0000">mov</font>     <font color="#ff0000">eax</font><font color="#9932cd"><strong>,</strong></font> <font color="#3080ca">-</font><font color="#802000">1</font> <font color="#238e23">; 先初始化eax</font><br /> </a><a name="L152">        <font color="#ff0000">or</font>      <font color="#ff0000">ebx</font><font color="#9932cd"><strong>,</strong></font> <font color="#ff0000">ebx</font><br /> </a><a name="L153">        <font color="#ff0000">jz</font>      <font color="#802000">$Done</font>   <font color="#238e23">; 避免出现I指?/font><br /> </a><a name="L154">@@<font color="#3080ca">:</font><br /> </a><a name="L155">        <font color="#ff0000">mov</font>     <font color="#ff0000">dl</font><font color="#9932cd"><strong>,</strong></font> <font color="#871f78">[</font><font color="#ff0000">ebx</font><font color="#871f78">]</font><br /> </a><a name="L156">        <font color="#ff0000">or</font>      <font color="#ff0000">dl</font><font color="#9932cd"><strong>,</strong></font> <font color="#ff0000">dl</font><br /> </a><a name="L157">        <font color="#ff0000">je</font>      <font color="#802000">$Done</font>    <font color="#238e23">;判断是否对字W串扫描完毕</font><br /> </a><a name="L158">        <br /> </a><a name="L159">         <font color="#238e23">;q里我用查表法来计算 CRC-32 Q因此非常快速:(x)</font><br /> </a><a name="L160">        <font color="#238e23">;因ؓ(f)q是assembly代码Q所以不需要给q个q程传递参敎ͼ只需要把oldcrc赋值给EAXQ以?qing)把byte赋值给DLQ?/font><br /> </a><a name="L161">        <font color="#238e23">;</font><br /> </a><a name="L162">        <font color="#238e23">; 在C语言中的形式Q?/font><br /> </a><a name="L163">        <font color="#238e23">;</font><br /> </a><a name="L164">        <font color="#238e23">;   temp = (oldcrc ^ abyte) & 0x000000FF;</font><br /> </a><a name="L165">        <font color="#238e23">;   crc  = (( oldcrc >> 8) & 0x00FFFFFF) ^ crc32tbl[temp];</font><br /> </a><a name="L166">        <font color="#238e23">;</font><br /> </a><a name="L167">        <font color="#238e23">; 参数Q?/font><br /> </a><a name="L168">        <font color="#238e23">;       EAX = old CRC-32</font><br /> </a><a name="L169">        <font color="#238e23">;        DL = a byte</font><br /> </a><a name="L170">        <font color="#238e23">; q回|(x)</font><br /> </a><a name="L171">        <font color="#238e23">;       EAX = new CRC-32</font><br /> </a><a name="L172">        <font color="#238e23">;       EDX = ?</font><br /> </a><a name="L173">               <br /> </a><a name="L174">        <font color="#ff0000">xor</font>     <font color="#ff0000">dl</font><font color="#9932cd"><strong>,</strong></font> <font color="#ff0000">al</font><br /> </a><a name="L175">        <font color="#ff0000">movzx</font>   <font color="#ff0000">edx</font><font color="#9932cd"><strong>,</strong></font> <font color="#ff0000">dl</font><br /> </a><a name="L176">        <font color="#ff0000">shr</font>     <font color="#ff0000">eax</font><font color="#9932cd"><strong>,</strong></font> <font color="#802000">8</font><br /> </a><a name="L177">        <font color="#ff0000">xor</font>     <font color="#ff0000">eax</font><font color="#9932cd"><strong>,</strong></font> <font color="#871f78">[</font>crc32tbl<font color="#3080ca">+</font><font color="#ff0000">edx</font><font color="#3080ca">*</font><font color="#802000">4</font><font color="#871f78">]</font><br /> </a><a name="L178">        <br /> </a><a name="L179">        <font color="#ff0000">inc</font>     <font color="#ff0000">ebx</font>        <br /> </a><a name="L180">        <font color="#ff0000">jmp</font>     @B<br /> </a><a name="L181"><br /> </a><a name="L182"><font color="#802000">$Done</font><font color="#3080ca">:</font><br /> </a><a name="L183">        <font color="#ff0000">not</font>     <font color="#ff0000">eax</font><br /> </a><a name="L184">        <font color="#ff0000">ret</font><br /> </a><a name="L185">arraycrc32      <font color="#ff0000">endp</font><br /> </a><a name="L186"><br /> </a><a name="L187"><font color="#ff0000">end</font> main<br /> </a><a name="L188"><font color="#238e23">;********************    over    ********************</font><br /> </a><a name="L189"><font color="#238e23">;by LC</font></a></td> </tr> </tbody> </table> <br /> <br /> 下面是它的资源文Ӟ(x)<br /> <br /> <table bgcolor="#fbedbb" border="0" cellpadding="0" cellspacing="0"> <tbody> <tr> <td><strong><br /> #include "resource.h"<br /> <br /> #define IDC_BUTTON_OPEN    3000<br /> #define IDC_EDIT_INPUT 3001<br /> #define IDC_STATIC -1<br /> <br /> LC_DIALOG DIALOGEX 10, 10, 195, 60<br /> STYLE DS_SETFONT | DS_CENTER | WS_MINIMIZEBOX | WS_VISIBLE | WS_CAPTION | <br />     WS_SYSMENU<br /> CAPTION "lc’s assembly framework"<br /> FONT 9, "?hu)?, 0, 0, 0x0<br /> BEGIN<br />     LTEXT           "误入一个字W串Q区分大写Q:(x)",IDC_STATIC,11,7,130,10<br />     EDITTEXT        IDC_EDIT_INPUT,11,20,173,12,ES_AUTOHSCROLL<br />     DEFPUSHBUTTON   "Ca&lc",IDC_BUTTON_OPEN,71,39,52,15<br /> END</strong></td> </tr> </tbody> </table> <br /> <br /> 如果你能够完全理解本节的内容Q那么请留意我的下一Ԍ我将具体介绍如何q用CRC-32对你的文件进行保护。(呵呵Q好戏在后头……Q? <img src ="http://www.aygfsteel.com/Todd/aggbug/321430.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/Todd/" target="_blank">Todd</a> 2010-05-20 01:45 <a href="http://www.aygfsteel.com/Todd/archive/2010/05/20/321430.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>矛与盄较量Q?Q——花指o(h)【{自老罗?/title><link>http://www.aygfsteel.com/Todd/archive/2010/05/20/321429.html</link><dc:creator>Todd</dc:creator><author>Todd</author><pubDate>Wed, 19 May 2010 17:44:00 GMT</pubDate><guid>http://www.aygfsteel.com/Todd/archive/2010/05/20/321429.html</guid><wfw:comment>http://www.aygfsteel.com/Todd/comments/321429.html</wfw:comment><comments>http://www.aygfsteel.com/Todd/archive/2010/05/20/321429.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/Todd/comments/commentRss/321429.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/Todd/services/trackbacks/321429.html</trackback:ping><description><![CDATA[<p> 有矛有盾?br /> 所以我们要讨论加密技术?br /> <br /> 我们知道Q所有的~译型语 aQ例如VC、BCB、Delphi和W(xu)in32ASM……最l都?x)把源代码编译成机器能识别??——因此也能够反过来把q些0?反编译成汇编? 码。反~译有什么用呢?试想惻I你辛辛苦苦写?jin)一个perfect的Y件出来,正准备把它卖?00万䆾Q忽?dng)在?jng)面上出现?jin)很多仿制你的? ?#8230;…hohoQ不知道你会(x)怎么惛_Q反正我是会(x)Ʋ哭无泪的。还有另外一U情况,你的软g是用注册码的形式来授权的Q每份license要卖30个美刀? 呵呵Q正当你在考虑着一q后是去加利尼亚还是夏威夷度假的时候,你的软g被Crack?jin)——也是_(d)你一分钱都不?x)得?#8230;…Q啊Q我惌楼啦Q!Q?br /> <br /> 所以我们要讨论如何l自qE序加密。这ơ就先说说最单的花指令?br /> <br /> 在解释这?#8220;花指?#8221;之前Q不妨先做几个小的实验?br /> <br /> 我们先来写一个程序,命名为hua.asmQ内容如下:(x)<br /> <br /> <table bgcolor="#cccccc" border="0" cellpadding="0" cellspacing="0"> <tbody> <tr> <td>;***************************************************************<br /> ;花指令实?<br /> ;作者:(x)|聪<br /> ;日期Q?002-8-21<br /> ;***************************************************************<br /> .386<br /> .model flat, stdcall<br /> option casemap:none<br /> <br /> include "masm32"include"windows.inc<br /> include "masm32"include"kernel32.inc<br /> include "masm32"include"user32.inc<br /> includelib "masm32"lib"kernel32.lib<br /> includelib "masm32"lib"user32.lib<br /> <br /> .data<br /> szText        db    "嘿嘿Q这是一个花指o(h)E序……", 0<br /> szCaption    db    "花指令演C?by LC 2002-8-21", 0<br /> <br /> .code<br /> main:<br />     jmp Do_It<br /> Do_It:<br />     invoke MessageBox, NULL, addr szText, addr szCaption, MB_OK<br />     invoke ExitProcess, 0<br /> end main</td> </tr> </tbody> </table> <br /> <br /> 然后用W32Dasm v10来反~译它,得到的结果如下:(x)Q由于篇q所限,q里只列出关键部分)(j)<br /> <br /> <br /> <table bgcolor="#cccccc" border="0" cellpadding="0" cellspacing="0"> <tbody> <tr> <td>+++++++++++++++++++ ASSEMBLY CODE LISTING ++++++++++++++++++<br /> //********************** Start of Code in Object .text **************<br /> Program Entry Point = 00401000 (hua.exe File Offset:00001600)<br /> <br /> <br /> <br /> //******************** Program Entry Point ********<br /> :00401000 EB00                    jmp 00401002<br /> <br /> * Referenced by a (U)nconditional or ?onditional Jump at Address:<br /> |:00401000(U)<br /> |<br /> :00401002 6A00                    push 00000000<br /> <br /> * Possible StringData Ref from Data Obj ->"花指令演C?by LC 2002-8-21"<br />                                   |<br /> :00401004 681F304000              push 0040301F<br /> <br /> * Possible StringData Ref from Data Obj ->"嘿嘿Q这是一个花指o(h)E序……"<br />                                   |<br /> :00401009 6800304000              push 00403000<br /> :0040100E 6A00                    push 00000000<br /> <br /> * Reference To: USER32.MessageBoxA, Ord:01BBh<br />                                   |<br /> :00401010 E80D000000              Call 00401022<br /> :00401015 6A00                    push 00000000<br /> <br /> * Reference To: KERNEL32.ExitProcess, Ord:0075h<br />                                   |<br /> :00401017 E800000000              Call 0040101C<br /> </td> </tr> </tbody> </table> <br /> <br /> 哇,好夸张啊Q你可能?x)说。反~译出来的代码几乎是跟源代码一一对应的,q样一来?我们的程序还有什么秘密可a呢?完全可以从反~译的结果中理解E序的功能?br /> <br /> 而且我们q可以在W32Dasm?#8220;String Data References”中得刎ͼ(x)<br /> <table bgcolor="#cccccc" border="0" cellpadding="0" cellspacing="0"> <tbody> <tr> <td>"嘿嘿Q这个是一个花指o(h)E序……"<br /> "花指令演C?by LC 2002-8-21"<br /> </td> </tr> </tbody> </table> <br /> <br /> 把刚才的源程序稍做修改,来做W二个实验:(x)<br /> <br /> <br /> <table bgcolor="#cccccc" border="0" cellpadding="0" cellspacing="0"> <tbody> <tr> <td>;***************************************************************<br /> ;花指令实?<br /> ;作者:(x)|聪<br /> ;日期Q?002-8-21<br /> ;***************************************************************<br /> .386<br /> .model flat, stdcall<br /> option casemap:none<br /> <br /> include "masm32"include"windows.inc<br /> include "masm32"include"kernel32.inc<br /> include "masm32"include"user32.inc<br /> includelib "masm32"lib"kernel32.lib<br /> includelib "masm32"lib"user32.lib<br /> <br /> .data<br /> szText        db    "嘿嘿Q这是一个花指o(h)E序……", 0<br /> szCaption    db    "花指令演C?by LC 2002-8-21", 0<br /> <br /> .code<br /> main:<br />     jz Do_It    ;注意q里和第一个实验中的源E序的区?br />     jnz Do_It    ;注意q里和第一个实验中的源E序的区?br /> Do_It:<br />     invoke MessageBox, NULL, addr szText, addr szCaption, MB_OK<br /> end main<br /> </td> </tr> </tbody> </table> <br /> <br /> 用W32Dasm反编译一下:(x)<br /> <br /> <table bgcolor="#cccccc" border="0" cellpadding="0" cellspacing="0"> <tbody> <tr> <td>+++++++++++++++++++ ASSEMBLY CODE LISTING ++++++++++++++++++<br /> //********************** Start of Code in Object .text **************<br /> Program Entry Point = 00401000 (hua.exe File Offset:00001600)<br /> <br /> <br /> <br /> //******************** Program Entry Point ********<br /> :00401000 7402                    je 00401004<br /> :00401002 7500                    jne 00401004<br /> <br /> * Referenced by a (U)nconditional or ?onditional Jump at Addresses:<br /> |:00401000?, :00401002?<br /> |<br /> :00401004 6A00                    push 00000000<br /> <br /> * Possible StringData Ref from Data Obj ->"花指令演C?by LC 2002-8-21"<br />                                   |<br /> :00401006 681F304000              push 0040301F<br /> <br /> * Possible StringData Ref from Data Obj ->"嘿嘿Q这是一个花指o(h)E序……"<br />                                   |<br /> :0040100B 6800304000              push 00403000<br /> :00401010 6A00                    push 00000000<br /> <br /> * Reference To: USER32.MessageBoxA, Ord:01BBh<br />                                   |<br /> :00401012 E801000000              Call 00401018<br /> </td> </tr> </tbody> </table> <br /> <br /> 可以看出Q这时的W32Dasm反编译出来的汇编指o(h)q是正确的。但是W32Dasm其实已经逐渐落入我们设下?#8220;陷阱”?jin)?br /> <br /> 下面我们来做W三个实验,把源E序Ҏ(gu)Q?br /> <br /> <table bgcolor="#cccccc" border="0" cellpadding="0" cellspacing="0"> <tbody> <tr> <td>;***************************************************************<br /> ;花指令实?<br /> ;作者:(x)|聪<br /> ;日期Q?002-8-21<br /> ;***************************************************************<br /> .386<br /> .model flat, stdcall<br /> option casemap:none<br /> <br /> include "masm32"include"windows.inc<br /> include "masm32"include"kernel32.inc<br /> include "masm32"include"user32.inc<br /> includelib "masm32"lib"kernel32.lib<br /> includelib "masm32"lib"user32.lib<br /> <br /> .data<br /> szText        db    "嘿嘿Q这是一个花指o(h)E序……", 0<br /> szCaption    db    "花指令演C?by LC 2002-8-21", 0<br /> <br /> .code<br /> main:<br />     jz Do_It    ;注意q里和第一个实验中的源E序的区?br />     jnz Do_It    ;注意q里和第一个实验中的源E序的区?br />     db 0E8h        ;注意q里和第二个实验中的源程序的区别<br /> Do_It:<br />     invoke MessageBox, NULL, addr szText, addr szCaption, MB_OK<br />     invoke ExitProcess, 0<br /> end main<br /> </td> </tr> </tbody> </table> <br /> <br /> 我们来看看W32Dasm中反~译出来的东西:(x)<br /> <br /> <table bgcolor="#cccccc" border="0" cellpadding="0" cellspacing="0"> <tbody> <tr> <td>+++++++++++++++++++ ASSEMBLY CODE LISTING ++++++++++++++++++<br /> //********************** Start of Code in Object .text **************<br /> Program Entry Point = 00401000 (hua.exe File Offset:00001600)<br /> <br /> <br /> <br /> //******************** Program Entry Point ********<br /> :00401000 7403                    je 00401005<br /> :00401002 7501                    jne 00401005<br /> :00401004 E86A00681D              call 1DA81073<br /> :00401009 304000                  xor byte ptr [eax+00], al<br /> <br /> * Possible StringData Ref from Data Obj ->"嘿嘿Q这是一个花指o(h)E序……"<br />                                   |<br /> :0040100C 6800304000              push 00403000<br /> :00401011 6A00                    push 00000000<br /> <br /> * Reference To: USER32.MessageBoxA, Ord:01BBh<br />                                   |<br /> :00401013 E80E000000              Call 00401026<br /> :00401018 6A00                    push 00000000<br /> <br /> * Reference To: KERNEL32.ExitProcess, Ord:0075h<br />                                   |<br /> :0040101A E801000000              Call 00401020<br /> </td> </tr> </tbody> </table> <br /> <br /> 呵呵Q很明显?jin),q时?00401004 ?00401009 行出错了(jin)Q而且q时查看“String Data References”Q也只剩下了(jin)Q?br /> <table bgcolor="#cccccc" border="0" cellpadding="0" cellspacing="0"> <tbody> <tr> <td>"嘿嘿Q这是一个花指o(h)E序……"</td> </tr> </tbody> </table> <br /> <br /> 让我们进一步隐藏信息,做第四个实验Q?br /> <br /> <table bgcolor="#cccccc" border="0" cellpadding="0" cellspacing="0"> <tbody> <tr> <td>;***************************************************************<br /> ;花指令实?<br /> ;作者:(x)|聪<br /> ;日期Q?002-8-21<br /> ;***************************************************************<br /> .386<br /> .model flat, stdcall<br /> option casemap:none<br /> <br /> include "masm32"include"windows.inc<br /> include "masm32"include"kernel32.inc<br /> include "masm32"include"user32.inc<br /> includelib "masm32"lib"kernel32.lib<br /> includelib "masm32"lib"user32.lib<br /> <br /> .data<br /> szText        db    "嘿嘿Q这是一个花指o(h)E序……", 0<br /> szCaption    db    "花指令演C?by LC 2002-8-21", 0<br /> <br /> .code<br /> main:<br />     jz Do_It    ;注意q里和第一个实验中的源E序的区?br />     jnz Do_It    ;注意q里和第一个实验中的源E序的区?br />     db 0E8h        ;注意q里和第二个实验中的源程序的区别<br /> Do_It:<br />     lea eax, szText        ;注意q里和第三个实验中的源程序的区别<br />     lea ebx, szCaption    ;注意q里和第三个实验中的源程序的区别<br />     invoke MessageBox, NULL, eax, ebx, MB_OK    ;注意q里和第三个实验中的源程序的区别<br />     invoke ExitProcess, 0<br /> end main<br /> </td> </tr> </tbody> </table> <br /> <br /> ~译Q再用W32Dasm反编译,得到的是Q?br /> <br /> <table bgcolor="#cccccc" border="0" cellpadding="0" cellspacing="0"> <tbody> <tr> <td>+++++++++++++++++++ ASSEMBLY CODE LISTING ++++++++++++++++++<br /> //********************** Start of Code in Object .text **************<br /> Program Entry Point = 00401000 (hua.exe File Offset:00001600)<br /> <br /> <br /> <br /> //******************** Program Entry Point ********<br /> :00401000 7403                    je 00401005<br /> :00401002 7501                    jne 00401005<br /> :00401004 E88D050030              call 30401596<br /> :00401009 40                      inc eax<br /> :0040100A 008D1D1D3040            add byte ptr [ebp+40301D1D], cl<br /> :00401010 006A00                  add byte ptr [edx+00], ch<br /> :00401013 53                      push ebx<br /> :00401014 50                      push eax<br /> :00401015 6A00                    push 00000000<br /> <br /> * Reference To: USER32.MessageBoxA, Ord:01BBh<br />                                   |<br /> :00401017 E80E000000              Call 0040102A<br /> :0040101C 6A00                    push 00000000<br /> <br /> * Reference To: KERNEL32.ExitProcess, Ord:0075h<br />                                   |<br /> :0040101E E801000000              Call 00401024<br /> </td> </tr> </tbody> </table> <br /> <br /> 呵呵Q这ơ不但面目全非了(jin)Q而且“String Data References”按钮已经变成?jin)灰艌Ӏ什么蛛丝马qw没有?jin)?br /> <br /> 各位看官看到q里明白?jin)吗Q其实花指o(h)是Zؓ(f)地构造一?#8220;陷阱”和一些无用的字节。例如第二个实验中的Q?br /> <br /> jz Do_It<br /> jnz Do_It<br /> <br /> 其实q个?jmp Do_It q(sh)是一样吗Q(呵呵Q如果在大学的期末考试里这样写Q一定会(x)被判不及(qing)?#8230;…Q?br /> <br /> 是的Q其实程序原有的功能和逻辑q是一L(fng)Q我们只不过是换?jin)一U表现Ş式而已。然而,反编译工h没有那么的,它们往往׃(x)把这些指令理解错Q从而错误地定?jin)指令的起始位置?br /> <br /> 要实现这U绝对蟩转的功能Q还可以用很多的Ҏ(gu)Q例如:(x)<br /> <br /> Push Do_It<br /> ret<br /> <br /> <br /> <strong>花指令是很容易理解的Q不q大家要注意适时而用Q不要滥用啊Q能起到qh破解者和隐藏信息的作用就行了(jin)Q不然将来要l护代码Ӟ我怕被qh的反而是你自己哦Q呵?#8230;…</strong> </p> <img src ="http://www.aygfsteel.com/Todd/aggbug/321429.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/Todd/" target="_blank">Todd</a> 2010-05-20 01:44 <a href="http://www.aygfsteel.com/Todd/archive/2010/05/20/321429.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>四个有用的过虑器http://www.aygfsteel.com/Todd/archive/2010/04/24/319270.htmlToddToddSat, 24 Apr 2010 08:36:00 GMThttp://www.aygfsteel.com/Todd/archive/2010/04/24/319270.htmlhttp://www.aygfsteel.com/Todd/comments/319270.htmlhttp://www.aygfsteel.com/Todd/archive/2010/04/24/319270.html#Feedback0http://www.aygfsteel.com/Todd/comments/commentRss/319270.htmlhttp://www.aygfsteel.com/Todd/services/trackbacks/319270.htmlimport javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 用于的 Browser 不缓存页面的qo(h)?br />  */
public class ForceNoCacheFilter implements Filter {

 public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException
 {
  ((HttpServletResponse) response).setHeader("Cache-Control","no-cache");
  ((HttpServletResponse) response).setHeader("Pragma","no-cache");
  ((HttpServletResponse) response).setDateHeader ("Expires", -1);
  filterChain.doFilter(request, response);
 }

 public void destroy()
 {
 }

    public void init(FilterConfig filterConfig) throws ServletException
 {
 }
}

二、检用h否登陆的qo(h)?/p>

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.List;
import java.util.ArrayList;
import java.util.StringTokenizer;
import java.io.IOException;

/**
 * 用于(g)用h否登陆的qo(h)器,如果未登录,则重定向到指的登录页?lt;p>
 * 配置参数<p>
 * checkSessionKey 需(g)查的?Session 中保存的关键?lt;br/>
 * redirectURL 如果用户未登录,则重定向到指定的面QURL不包?ContextPath<br/>
 * notCheckURLList 不做(g)查的URL列表Q以分号分开Qƈ?URL 中不包括 ContextPath<br/>
 */
public class CheckLoginFilter
 implements Filter
{
    protected FilterConfig filterConfig = null;
    private String redirectURL = null;
    private List notCheckURLList = new ArrayList();
    private String sessionKey = null;

 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException
 {
  HttpServletRequest request = (HttpServletRequest) servletRequest;
  HttpServletResponse response = (HttpServletResponse) servletResponse;

   HttpSession session = request.getSession();
  if(sessionKey == null)
  {
   filterChain.doFilter(request, response);
   return;
  }
  if((!checkRequestURIIntNotFilterList(request)) && session.getAttribute(sessionKey) == null)
  {
   response.sendRedirect(request.getContextPath() + redirectURL);
   return;
  }
  filterChain.doFilter(servletRequest, servletResponse);
 }

 public void destroy()
 {
  notCheckURLList.clear();
 }

 private boolean checkRequestURIIntNotFilterList(HttpServletRequest request)
 {
  String uri = request.getServletPath() + (request.getPathInfo() == null ? "" : request.getPathInfo());
  return notCheckURLList.contains(uri);
 }

 public void init(FilterConfig filterConfig) throws ServletException
 {
  this.filterConfig = filterConfig;
  redirectURL = filterConfig.getInitParameter("redirectURL");
  sessionKey = filterConfig.getInitParameter("checkSessionKey");

  String notCheckURLListStr = filterConfig.getInitParameter("notCheckURLList");

  if(notCheckURLListStr != null)
  {
   StringTokenizer st = new StringTokenizer(notCheckURLListStr, ";");
   notCheckURLList.clear();
   while(st.hasMoreTokens())
   {
    notCheckURLList.add(st.nextToken());
   }
  }
 }
}

三、字W编码的qo(h)?/p>

import javax.servlet.*;
import java.io.IOException;

/**
 * 用于讄 HTTP h字符~码的过滤器Q通过qo(h)器参数encoding指明使用何种字符~码,用于处理Html Formh参数的中文问?br />  */
public class CharacterEncodingFilter
 implements Filter
{
 protected FilterConfig filterConfig = null;
 protected String encoding = "";

 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException
 {
        if(encoding != null)
         servletRequest.setCharacterEncoding(encoding);
        filterChain.doFilter(servletRequest, servletResponse);
 }

 public void destroy()
 {
  filterConfig = null;
  encoding = null;
 }

    public void init(FilterConfig filterConfig) throws ServletException
 {
         this.filterConfig = filterConfig;
        this.encoding = filterConfig.getInitParameter("encoding");

 }
}

四、资源保护过滤器

package catalog.view.util;
import javax.servlet.Filter;
import javax.servlet.FilterConfig;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Iterator;
import java.util.Set;
import java.util.HashSet;
//
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* This Filter class handle the security of the application.
*

* It should be configured inside the web.xml. * * @author Derek Y. Shen */ public class SecurityFilter implements Filter { //the login page uri private static final String LOGIN_PAGE_URI = "login.jsf"; //the logger object private Log logger = LogFactory.getLog(this.getClass()); //a set of restricted resources private Set restrictedResources; /** * Initializes the Filter. */ public void init(FilterConfig filterConfig) throws ServletException { this.restrictedResources = new HashSet(); this.restrictedResources.add("/createProduct.jsf"); this.restrictedResources.add("/editProduct.jsf"); this.restrictedResources.add("/productList.jsf"); } /** * Standard doFilter object. */ public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { this.logger.debug("doFilter"); String contextPath = ((HttpServletRequest)req).getContextPath(); String requestUri = ((HttpServletRequest)req).getRequestURI(); this.logger.debug("contextPath = " + contextPath); this.logger.debug("requestUri = " + requestUri); if (this.contains(requestUri, contextPath) && !this.authorize((HttpServletRequest)req)) { this.logger.debug("authorization failed"); ((HttpServletRequest)req).getRequestDispatcher(LOGIN_PAGE_URI).forward(req, res); } else { this.logger.debug("authorization succeeded"); chain.doFilter(req, res); } } public void destroy() {} private boolean contains(String value, String contextPath) { Iterator ite = this.restrictedResources.iterator(); while (ite.hasNext()) { String restrictedResource = (String)ite.next(); if ((contextPath + restrictedResource).equalsIgnoreCase(value)) { return true; } } return false; } private boolean authorize(HttpServletRequest req) { //处理用户d /* UserBean user = (UserBean)req.getSession().getAttribute(BeanNames.USER_BEAN); if (user != null && user.getLoggedIn()) { //user logged in return true; } else { return false; }*/ } }



Todd 2010-04-24 16:36 发表评论
]]>
Java防止非法和重复表单提?/title><link>http://www.aygfsteel.com/Todd/archive/2010/04/23/319184.html</link><dc:creator>Todd</dc:creator><author>Todd</author><pubDate>Fri, 23 Apr 2010 03:22:00 GMT</pubDate><guid>http://www.aygfsteel.com/Todd/archive/2010/04/23/319184.html</guid><wfw:comment>http://www.aygfsteel.com/Todd/comments/319184.html</wfw:comment><comments>http://www.aygfsteel.com/Todd/archive/2010/04/23/319184.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/Todd/comments/commentRss/319184.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/Todd/services/trackbacks/319184.html</trackback:ping><description><![CDATA[<p>真是一切都逃不qsession,看了(jin)DZ的formhash;struts token什么啊Q就是个session,安全U别比验证码q(sh)?br /> <strong>看看别h的分析有益n?j)啊Q看之,目前来讲一切都逃不qsession<br /> <br /> <br /> 预期辑ֈ目标</strong><span style="font-size: 9pt; color: #333333">:</span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; color: #333333">       <span style="background: #d9d9d9">1</span></span>、当用户q行的是<span style="font-size: 9pt; background: #d9d9d9; color: #333333">Refresh/Reload/Back/Forward</span>操作、以?qing)?span style="font-size: 9pt; background: #d9d9d9; color: #333333">Back</span>?span style="font-size: 9pt; background: #d9d9d9; color: #333333">Submit</span>操作Ӟ仅仅?span style="font-size: 9pt; background: #d9d9d9; color: #333333">reloading</span>先前的结果页?/p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">       2</span>、当用户重复提交同一个Q务操作时<span style="font-size: 9pt; background: #d9d9d9; color: #333333">,</span>后台服务接收q处理第一ơ提交的dQ后面提交不起作用(不{向也不提C)(j)?/p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">       3</span>、该功能h公用性?/p> <p style="text-align: left" align="left"><strong>基本形成思\Q?/strong></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; color: #333333">       1</span>、在<span style="font-size: 9pt; color: #333333">basic filter</span>中实现公用?/p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; color: #333333">                <span style="background: #d9d9d9">if(true){//</span></span>问题<span style="font-size: 9pt; background: #d9d9d9; color: #333333">1</span>Q如何确定是否ؓ(f)重复提交</p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                         ...</span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                         chain.doFilter(request,response);</span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                }else{</span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                         //</span>问题<span style="font-size: 9pt; background: #d9d9d9; color: #333333">2</span>Q如何实C转向、不提示也不昄I白?/p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                }</span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; color: #333333">       2</span>、网上资料概?/p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; color: #333333">                <span style="background: #d9d9d9">a</span></span>、提交表单后按钮变灰<span style="font-size: 9pt; background: #d9d9d9; color: #333333">/</span>隐藏提交按钮</p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                b</span>、在<span style="font-size: 9pt; background: #d9d9d9; color: #333333">js</span>里设|全局变量Q提交后修改该变量的|依据变量的值判断是否重复提?/p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                         var flag=true;</span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                         function checkForm(){</span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                                   if (flag==false){</span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                                            return;</span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                                   }</span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                         </span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                                   flag=false;</span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                                   document.form1.submit();</span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                         </span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                         }</span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                c</span>?span style="font-size: 9pt; background: #d9d9d9; color: #333333">struts </span>Q?span style="font-size: 9pt; background: #d9d9d9; color: #333333">webwork</span>没有扑ֈq个资料Q?/p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                         //</span>验证事务控制令牌<span style="font-size: 9pt; background: #d9d9d9; color: #333333">,<html:form ></span>?x)自动根?span style="font-size: 9pt; background: #d9d9d9; color: #333333">session</span>中标识生成一个隐?span style="font-size: 9pt; background: #d9d9d9; color: #333333">input</span>代表令牌Q防止两ơ提?/p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                         </span>?span style="font-size: 9pt; background: #d9d9d9; color: #333333">action</span>中:(x)</p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                         </span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                                //<input type="hidden" name="org.apache.struts.taglib.html.TOKEN" value="6aa35341f25184fd996c4c918255c3ae"></span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                         </span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                                if (!isTokenValid(request))</span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                                    errors.add(ActionErrors.GLOBAL_ERROR,</span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                                               new ActionError("error.transaction.token"));</span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                                resetToken(request); //</span>删除<span style="font-size: 9pt; background: #d9d9d9; color: #333333">session</span>中的令牌</p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                         </span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                         action</span>有这L(fng)一个方法生成o(h)牌华</p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                            protected String generateToken(HttpServletRequest request) {</span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                         </span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                                HttpSession session = request.getSession();</span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                                try {</span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                                    byte id[] = session.getId().getBytes();</span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                                    byte now[] =</span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                                        new Long(System.currentTimeMillis()).toString().getBytes();</span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                                    MessageDigest md = MessageDigest.getInstance("MD5");</span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                                    md.update(id);</span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                                    md.update(now);</span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                                    return (toHex(md.digest()));</span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                                } catch (IllegalStateException e) {</span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                                    return (null);</span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                                } catch (NoSuchAlgorithmException e) {</span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                                    return (null);</span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                                }</span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                         </span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                            }           </span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                d</span>、用户用浏览器Ӟ可以l常使用向后的按钮,因此有可能重复提交一个他们已l提交过?span style="font-size: 9pt; background: #d9d9d9; color: #333333">form</span>Q这样就?x)带来一个重复事务处理的问题。同P一个用户也可能在接收到一个确认的面之前按下停止的按钮,接着再次提交同一?span style="font-size: 9pt; background: #d9d9d9; color: #333333">form</span>。对于这些情况,我们都想跟踪q且止q些重复的提交,我们可以使用一个控?span style="font-size: 9pt; background: #d9d9d9; color: #333333">servlet</span>来提供一个控制点Q以解决q个问题?/p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                </span>  同步记号Q?span style="font-size: 9pt; background: #d9d9d9; color: #333333">Synchronizer (or Dvu) Token</span>Q?/p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="font-size: 9pt; background: #d9d9d9; color: #333333">                </span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left">q个{略是ؓ(f)?jin)解决重复?span style="font-size: 9pt; background: #d9d9d9; color: #333333">form</span>提交问题。一个同步的记号被设|在一个用L(fng)<span style="font-size: 9pt; background: #d9d9d9; color: #333333">Session</span>中,q且包含在返回到客户的每一?span style="font-size: 9pt; background: #d9d9d9; color: #333333">form</span>中。当<span style="font-size: 9pt; background: #d9d9d9; color: #333333">form</span>被提交时Q?span style="font-size: 9pt; background: #d9d9d9; color: #333333">form</span>中的同步标记和<span style="font-size: 9pt; background: #d9d9d9; color: #333333">Session</span>中的同步标记作对比。在<span style="font-size: 9pt; background: #d9d9d9; color: #333333">form</span>首次提交的时候,q两个标记应该是一L(fng)。如果标C一P那么?span style="font-size: 9pt; background: #d9d9d9; color: #333333">form</span>׃(x)止提交Q一个错误就?x)返回给用户。在用户提交一?span style="font-size: 9pt; background: #d9d9d9; color: #333333">form</span>Ӟ如果按下览器中的后退按钮q尝试重新提交同一?span style="font-size: 9pt; background: #d9d9d9; color: #333333">form</span>Ӟ标记׃(x)出现不匹配的现象?/p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left"><span style="color: #000000">另一斚wQ如果两个标记值匹配,那么我们可以确信整个流E是正确的。在q种情况下,Session中的标记值就?x)被修改Z个新的|同时允许提交该form?                                  你也可以使用q个{略来控制对某些面的直接访问,好象上面资源保护中描述的一栗例如,假设一个用户将某个应用的页面A收藏到收藏夹中,而页面A只允?dng)R过面B和C讉K。当用户直接通过收藏Ҏ(gu)讉K面AQ这旉面的讉K序是不正的Q这样同步标记将处在一个不同步的状态,或者它Ҏ(gu)׃存在。不论怎样Q访问都被禁止了(jin)?                e、做一个hidden框,名字自己定,提交后得到这个值放入sessionQ提交前判断session是否为空   解决Ҏ(gu)Q?       1、后台公q中实现前台的Form中自动生成两个hidden文本功能Q一个是作page是否重复提交判断Qƈql自动附上关键|如struts采用的方案)(j)Q另一个作为button是否重复提交判断Qstruts中好像没有)(j)。由后台公共cd现界面两个hidden text自动生成的好处在于公用性?       2、在basic filter中根据两个hidden text值判断是否ؓ(f)重复提交?       3、javascript中作一个公共方法,实现功能Q如果需要判断是否重复提交,qW二个hidden text附上关键|q该功能不可用?. 个h感想Q我怿未来该功能一定会(x)被服务器集成Q而不再由开发h员进行编?</span></p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left">----------------------------------------CZ代码----------------------------------------------------</p> <p style="text-indent: 27pt; line-height: 12pt; text-align: left" align="left">W一Q对于不支持POST的,可以单的使用如下代码<br /> if ("POST".equals(request.getMethod())) ...{<br />   // 正常q行<br /> }else...{<br />   // 异常h<br />   out.print("异常讉K");<br />   return;<br /> }<br /> 如果是servlet, 可以doGetҎ(gu)直接q回Q不q行处理p?br /> public void doGet(HttpServletRequest request, HttpServletResponse response) ...{<br />   return;<br /> }<br /> public void doPost(HttpServletRequest request, HttpServletResponse response) ...{<br />   // 正常q行操作<br /> }<br /> q可以采用特定的标志来区分,比如 <br /> <form><input type="hidden" name="action" value="insert"/></form> <br /> E序里这样判?br /> if ("POST".equals(request.getMethod()) && ("insert".equals(request.getParameter("action")))) ...{<br />   // 正常q行<br /> }else...{<br />   // 异常h<br />   out.print("异常讉K");<br />   return;<br /> }<br /> W二Q判断提交的来源referer,代码如下<br /> if ("POST".equals(request.getMethod())) ...{<br />   String referer = request.getHeader("referer");<br />   if (referer == null || !referer.startsWith("<a href="http://%22+request.getservername/">http://"+request.getServerName</a>())) ...{<br />     // 非法来源<br />     return;<br />   }<br />   // 正常q行<br /> }else...{<br />   // 异常h<br />   out.print("异常讉K");<br />   return;<br /> }<br /> W三 防止重复提交的hashCode <br /> 在表单显C页?br />   //生成一个formhash,法可以自己定,不随侉K复就可以?br />   String formhash = MD5.encode(Long.toString(new Date().getTime()));<br />   //d当前session里面的hashCode集合Q此处用了(jin)SetQ方便判断?br />   Set<String> formhashSession = (Set<String>) session.getAttribute("formhashSession");<br />   if (formhashSession == null) ...{<br />     formhashSession = new HashSet<String>();<br />   }<br />   // (g)重复问?br />   while (formhashSession.contains(formhash)) ...{<br />     formhash = MD5.encode(Long.toString(new Date().getTime()));<br />   }<br />   // 保存到session里面<br />   formhashSession.add(formhash);<br />   // 保存<br />   session.setAttribute("formhashSession", formhashSession);<br /> 表单里面增加如下字段<br /> <input type="hidden" name="formhash" id="formhash" value="<%=formhash%>" /> <br /> 在表单提交页面进行如下处?br />     // 拿到表单的formhash<br />     String formhash = upload.getParameter("formhash");<br />     // 拿到session里面的集?br />     Set<String> formhashSession = (Set<String>) session.getAttribute("formhashSession");<br />     // 如果没有Q则是重复提交,或者非法提?br />     if (formhashSession == null || !formhashSession.contains(formhash)) ...{<br />       out.println("请不要重复提交!");<br />       return;<br />     }<br />     // 下面q行其它的操?br />     // <br />     // 最?如果操作成功,从session里面把这个formhash 删掉Q?br />     // 以免用户填写了(jin)某个字段Q造成表单无法再次提交<br />     formhashSession.remove(formhash);<br />     session.setAttribute("formhashSession", formhashSession);</p> <img src ="http://www.aygfsteel.com/Todd/aggbug/319184.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/Todd/" target="_blank">Todd</a> 2010-04-23 11:22 <a href="http://www.aygfsteel.com/Todd/archive/2010/04/23/319184.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【{】黑客攻破apache.org官网http://www.aygfsteel.com/Todd/archive/2010/04/22/319162.htmlToddToddThu, 22 Apr 2010 15:51:00 GMThttp://www.aygfsteel.com/Todd/archive/2010/04/22/319162.htmlhttp://www.aygfsteel.com/Todd/comments/319162.htmlhttp://www.aygfsteel.com/Todd/archive/2010/04/22/319162.html#Feedback0http://www.aygfsteel.com/Todd/comments/commentRss/319162.htmlhttp://www.aygfsteel.com/Todd/services/trackbacks/319162.html
1、通过跨站漏洞Cַ?jin)几个管理员Q获得JIRAQ一个项目管理程序)(j)后台理权限Qƈ修改相关讄Q上传jsp木马?br />
2、在后台看到其他用户的帐P通过登陆入口暴力跑密码,破解?jin)几百个帐号?br />
官方说是“At the same time as the XSS attack”Q我不这么认为,我认为是获取后台之后Q能看到帐号?jin),才可以高效率的破解密码。如果不通过后台可以破解几百个帐号Q那q个事情早就发生?jin)?br />
3、部|了(jin)一个JARQ可以记录登陆帐号及(qing)密码Q然后用JIRA的系l发邮glapache的管理h员说Q?#8220;JIRA出现故障?jin),请你使用邮g里的临时密码登陆Qƈ修改密码”Q相关h员登陆了(jin)Qƈ把密码修Ҏ(gu)自己常用的密码,当然Q这些密码都被记录下来了(jin) Q)(j)

4、正如黑客所计的,上述被记录的密码中,有密码可以登陆brutus.apache.orgQ更让黑客开?j)和省?j)的是Q这个可以登陆的帐号竟然具备完全的sodu权限Q提权都不用提了(jin)Q直接就是rootQ真是爽的一塌糊涂啊。而这个被root的brutus.apache.org上面跑着JIRA、Confluence和Bugzilla?br />
5、brutus.apache.org上的部分用户保存?sh)(jin)subversion的密码,黑客用这些密码登陆了(jin)people.apache.orgQ但是ƈ没获得其他权限。这个people.apache.org可是apache的主服务器之一Q如果root?jin)这个机器,那基本可以获得所有apache主要人员的密码了(jin)。可惜,黑客们功亏一?br />
整个故事到此l束Q下面说说Apache是如何发现自p入R的?br />
Ҏ(gu)a(chn)pache官方的描q?#8220;About 6 hours after they started resetting passwords, we noticed the attackers and began shutting down services”Q我猜测apache是因为黑客重设了(jin)用户密码q个行ؓ(f)才发现被入R的?br />
如果说的是黑客重讄是JIRA的密码,那么是因ؓ(f)黑客做戏没做_套导致的Q可能apache理人员?sh)去看之后,发现没啥问题Q被忽?zhn)了(jin)?br />
如果说的是黑客重讑օ他密码,我想不到整个q程中还需要重设什么其他的密码?br />
我还是对apache的安全措施非常好奇,到底是如何发现的Q到底是相关人员安全敏感度高呢,q是黑客留下?jin)一些痕q被安全(g)查措施发C(jin)。如果是后者的话,(g)查周期又是多长呢Q?4时Q?br />
l验教训Q?br />
回头再看看黑客的整个dq程Q素包子怿在细节上?x)有很多可以吸取教训的地斏V从长远来看Q可以加强安全意识培训、实施SDL安全开发生命周期、日志集中分析、主机入侉|系l等{,q些都是需要企业的安全部门长期投入d的事情;相对短^快的Ҏ(gu)是要求重要的人员、重要的应用、重要的pȝ使用双因素动态密码认证?br />


Todd 2010-04-22 23:51 发表评论
]]>
Googled最新调查结果曝光:(x)密码pȝ受害http://www.aygfsteel.com/Todd/archive/2010/04/22/319161.htmlToddToddThu, 22 Apr 2010 15:49:00 GMThttp://www.aygfsteel.com/Todd/archive/2010/04/22/319161.htmlhttp://www.aygfsteel.com/Todd/comments/319161.htmlhttp://www.aygfsteel.com/Todd/archive/2010/04/22/319161.html#Feedback0http://www.aygfsteel.com/Todd/comments/commentRss/319161.htmlhttp://www.aygfsteel.com/Todd/services/trackbacks/319161.html《纽U时报》网??9日发表文?/a>透露Q据一位了(jin)解Googled12月遭受攻击调查细节的专家在几天前的一ơ安全技术会(x)议上描述Q受到攻ȝpȝ中,包括代号为Gaia的Google内部密码pȝ。Google的员工和成百万全世界的用户都通过q个pȝd?Gmail和其他各U网上服务?/p>

目前没有证据表明有Gmail用户的密码被盗。Google公司斚w表示Q在受到d数小时后Q公司就ȀzM(jin)Gmail新的加密层,而且加强?jin)数?中心(j)的安全性,q进一步加Z(jin)其网上服务与用户计算Z间通信q接的安全。但是,有安全分析h员指出,d者在d?jin)内部密码系l之后,有可能在Gaia pȝ和Google全球数据中心(j)中安装木马,只不q在Google的安全专家获知受d之后Q这变得非常困难。另外,d者在获取?jin)系l的源代码ƈ?jin)解?pȝq作机理之后Q也有可能(虽然可能性不大)(j)发现Googleq(sh)知道的安全漏z,q种隐?zhn)很o(h)安全专家头痛?/p>

文中q解释了(jin)此次Google所受攻ȝ详细q程Q?/p>

1. d者首先通过微YMSNl一个Google中国的员工A发去一条即时消息?/p>

2. q个员工在不知情的情况下点击?jin)其中的|址Qƈ讉K?#8220;已污染的”|站Qd者获得了(jin)讉KA使用的计机的权限?/p>

3. d者由此访问了(jin)Google公司的内部目录系l(名ؓ(f)MomaQ,其中保存着所有Google员工的工作情况,包括具体员工的信息?/p>

4. 在查扑ֈ?jin)位于Google国总部的Gaia软g开发者的名字之后Q他们而首先尝试访问开发者的工作?sh)脑?/p>

5. 然后使用?jin)一q串复杂的技术获取了(jin)Gaiapȝ源代码库的访问权限?/p>

6. 接下来,他们把偷到的软g传输C计算服务提供商Rackspace的计机上,此后再传到哪里,׃再ؓ(f)人所知?/p>

文中_(d)Gaiapȝ目前仍然在用,现在的正式名U被UCؓ(f)Single Sign-On?/p>

本周一Google的高拒l对此进行评论,说其中暴露的安全问题早已l解冟?/p>

有安全专家表C,新的dl节很可能增加h们对云计安全的担心(j)。由于v量的信息现在被相寚w中存攑֜一些计机pȝ中,单点被攻破就可能带来N 性的损失?/p>

Todd 2010-04-22 23:49 发表评论
]]>
apache ab 使用http://www.aygfsteel.com/Todd/archive/2010/04/22/319160.htmlToddToddThu, 22 Apr 2010 15:29:00 GMThttp://www.aygfsteel.com/Todd/archive/2010/04/22/319160.htmlhttp://www.aygfsteel.com/Todd/comments/319160.htmlhttp://www.aygfsteel.com/Todd/archive/2010/04/22/319160.html#Feedback0http://www.aygfsteel.com/Todd/comments/commentRss/319160.htmlhttp://www.aygfsteel.com/Todd/services/trackbacks/319160.html 参数Q?br />     -n requests     Number of requests to perform
    //在测试会(x)话中所执行的请求个数。默认时Q仅执行一个请?/font>
    -c concurrency Number of multiple requests to make
    //一ơ生的h个数。默认是一ơ一个?
    -t timelimit    Seconds to max. wait for responses
    //试所q行的最大秒数。其内部隐含值是-n 50000。它可以使对服务器的试限制在一个固定的L间以内。默认时Q没有时间限制?br />     -p postfile     File containing data to POST
    //包含?jin)需要POST的数据的文g.
    -T content-type Content-type header for POSTing
    //POST数据所使用的Content-type头信息?/font>
    -v verbosity    How much troubleshooting info to print
    //讄昄信息的详l程?- 4或更大g(x)昄头信息, 3或更大值可以显C响应代?404, 200{?, 2或更大值可以显C告和其他信息?-V 昄版本号ƈ退出?br />     -w              Print out results in HTML tables
    //以HTML表的格式输出l果。默认时Q它是白色背景的两列宽度的一张表?br />     -i              Use HEAD instead of GET
   // 执行HEADhQ而不是GET?/font>
    -x attributes   String to insert as table attributes
    //
    -y attributes   String to insert as tr attributes
    //
    -z attributes   String to insert as td or th attributes
    //
    -C attribute    Add cookie, eg. 'Apache=1234. (repeatable)
    //-C cookie-name=value 对请求附加一个Cookie:行?其典型Ş式是name=value的一个参数对。此参数可以重复?/font>
    -H attribute    Add Arbitrary header line, eg. 'Accept-Encoding: gzip'
                    Inserted after all normal header lines. (repeatable)
    -A attribute    Add Basic WWW Authentication, the attributes
                    are a colon separated username and password.
    -P attribute    Add Basic Proxy Authentication, the attributes
                    are a colon separated username and password.
    //-P proxy-auth-username:password 对一个中转代理提供BASIC认证信Q。用户名和密码由一?隔开Qƈ以base64~码形式发送。无论服务器是否需?? 是否发送了(jin)401认证需求代?Q此字符串都?x)被发送?/font>
    -X proxy:port   Proxyserver and port number to use
    -V              Print version number and exit
    -k              Use HTTP KeepAlive feature
    -d              Do not show percentiles served table.
    -S              Do not show confidence estimators and warnings.
    -g filename     Output collected data to gnuplot format file.
    -e filename     Output CSV file with percentages served
    -h              Display usage information (this message)
    //-attributes 讄 属性的字符? ~陷E序中有各种?rn)态声明的固定长度的缓冲区。另外,对命令行参数、服务器的响应头和其他外部输入的解析也很单,q可能会(x)有不良后果。它没有完整地实现HTTP/1.x; 仅接受某?预想'的响应格式?strstr(3)的频J用可能会(x)带来性能问题Q即, 你可能是在测试ab而不是服务器的性能?

参数很多,一般我们用 -c ?-n 参数可以了(jin). 例如:

./ab -c 1000 -n 1000 http://127.0.0.1/index.php

q个表示同时处理1000个请求ƈq行1000ơindex.php文g.
#/usr/local/xiaobai/apache2054/bin/ab -c 1000 -n 1000 http://127.0.0.1/index.html.zh-cn.gb2312
This is ApacheBench, Version 2.0.41-dev <$Revision: 1.121.2.12 $> apache-2.0
Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright (c) 1998-2002 The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Finished 1000 requests


Server Software:        Apache/2.0.54
//q_apache 版本2.0.54
Server Hostname:        127.0.0.1
//服务器主机名
Server Port:            80
//服务器端?/font>

Document Path:          /index.html.zh-cn.gb2312
//试的页面文?/font>
Document Length:        1018 bytes
//文档大小

Concurrency Level:      1000
//q发?br /> Time taken for tests:   8.188731 seconds
//整个试持箋(hu)的时?/font>
Complete requests:      1000
//完成的请求数?/font>
Failed requests:        0
//p|的请求数?/font>
Write errors:           0

Total transferred:      1361581 bytes
//整个场景中的|络传输?/font>
HTML transferred:       1055666 bytes
//整个场景中的HTML内容传输?br /> Requests per second:    122.12 [#/sec] (mean)
//大家最兛_(j)的指标之一Q相当于 LR 中的 每秒事务?/span> Q后面括号中?/span> mean 表示q是一个^均?/span>
Time per request:       8188.731 [ms] (mean)
//大家最兛_(j)的指标之二,相当?/span> LR 中的 q_事务响应旉 Q后面括号中?/span> mean 表示q是一个^均?/span>
Time per request:       8.189 [ms] (mean, across all concurrent requests)
//每个h实际q行旉的^均?/font>
Transfer rate:          162.30 [Kbytes/sec] received
//q_每秒|络上的量Q可以帮助排除是否存在网l流量过大导致响应时间g长的问题

Connection Times (ms)
              min mean[+/-sd] median   max
Connect:        4 646 1078.7     89    3291
Processing:   165 992 493.1    938    4712
Waiting:      118 934 480.6    882    4554
Total:        813 1638 1338.9   1093    7785
//|络上消耗的旉的分解,各项数据的具体算法还?sh)是很清?/span>

Percentage of the requests served within a certain time (ms)
50%   1093
66%   1247
75%   1373
80%   1493
90%   4061
95%   4398
98%   5608
99%   7368
100%   7785 (longest request)
//整个场景中所有请求的响应情况。在场景中每个请求都有一个响应时_(d)其中50Q的用户响应旉于1093 毫秒Q?0Q?的用户响应时间小?247 毫秒Q最大的响应旉于7785 毫秒

      ׃对于q发hQcpu实际上ƈ不是同时处理的,而是按照每个h获得的时间片逐个轮{处理的,所以基本上W一个Time per request旉U等于第二个Time per request旉乘(sh)q发h?/font>



Todd 2010-04-22 23:29 发表评论
]]>
վ֩ģ壺 ԫ| | ߰| | | | ɽ| | ˮ| | | ǿ| | | | ֲ| ¡| Т| | | ڰ| غ| | | | ӻ| | | | ٲ| ԭ| | | ˹| Ϫ| | | | | | |