﻿<?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>BlogJava-Todd-随笔分类-c++</title><link>http://www.blogjava.net/Todd/category/44949.html</link><description /><language>zh-cn</language><lastBuildDate>Wed, 08 Feb 2012 21:14:00 GMT</lastBuildDate><pubDate>Wed, 08 Feb 2012 21:14:00 GMT</pubDate><ttl>60</ttl><item><title>【1】freebsd  安装，环境，资料</title><link>http://www.blogjava.net/Todd/archive/2012/02/09/369634.html</link><dc:creator>Todd</dc:creator><author>Todd</author><pubDate>Wed, 08 Feb 2012 17:26:00 GMT</pubDate><guid>http://www.blogjava.net/Todd/archive/2012/02/09/369634.html</guid><wfw:comment>http://www.blogjava.net/Todd/comments/369634.html</wfw:comment><comments>http://www.blogjava.net/Todd/archive/2012/02/09/369634.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Todd/comments/commentRss/369634.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Todd/services/trackbacks/369634.html</trackback:ping><description><![CDATA[<div>1.中文使用手册 必备<br /><a href="http://www.freebsd.org/doc/zh_CN/books/handbook/index.html">http://www.freebsd.org/doc/zh_CN/books/handbook/index.html</a><br />开发手册<br /><a href="http://www.freebsd.org/doc/en/books/developers-handbook/index.html">http://www.freebsd.org/doc/en/books/developers-handbook/index.html</a><br />2.系统安装<br />系统安装包FreeBSD-8.2-RELEASE-i386-disc1.iso 地址：<br /><a href="ftp://ftp.freebsd.org/pub/FreeBSD/releases/i386/ISO-IMAGES/8.2/">ftp://ftp.freebsd.org/pub/FreeBSD/releases/i386/ISO-IMAGES/8.2/</a><br />或者使用网易的镜像地址下载：<br /><a href="http://mirrors.163.com/FreeBSD/ISO-IMAGES-i386/8.2/">http://mirrors.163.com/FreeBSD/ISO-IMAGES-i386/8.2/</a><br />使用虚拟光驱加载iso文件，在vm中加载安装<br />安装步骤参见《手册》地址：<br /><a href="http://www.freebsd.org/doc/zh_CN/books/handbook/using-sysinstall.html">http://www.freebsd.org/doc/zh_CN/books/handbook/using-sysinstall.html</a><br />我使用标准安装，安装步骤很详细，若要ssh,标准安装中带ssh,检查下rc.conf中<pre class="SCREEN">sshd_enable="YES"
</pre><br />gcc也是自带装好的，可以hello验证下<br />#include &lt;stdio.h&gt;<br />int main()<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("hello,todd^^\n");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<br />}<br />&gt;gcc hello.c -o hello<br />&gt;./hello<br />&gt;hello,todd^^<br />欧了<br /><br /><br /><br /><br /></div><img src ="http://www.blogjava.net/Todd/aggbug/369634.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Todd/" target="_blank">Todd</a> 2012-02-09 01:26 <a href="http://www.blogjava.net/Todd/archive/2012/02/09/369634.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>图像旋转公式 </title><link>http://www.blogjava.net/Todd/archive/2011/04/16/348387.html</link><dc:creator>Todd</dc:creator><author>Todd</author><pubDate>Fri, 15 Apr 2011 17:10:00 GMT</pubDate><guid>http://www.blogjava.net/Todd/archive/2011/04/16/348387.html</guid><wfw:comment>http://www.blogjava.net/Todd/comments/348387.html</wfw:comment><comments>http://www.blogjava.net/Todd/archive/2011/04/16/348387.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Todd/comments/commentRss/348387.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Todd/services/trackbacks/348387.html</trackback:ping><description><![CDATA[　 图像旋转是指把定义的图像绕某一点以逆时针或顺时针方向旋转一定的角度，通常是指绕图像的中心以逆时针方向旋转。
<p>　　 假设图像的左上角为（left, top),右下角为（right, bottom)，则图像上任意点（x0, y0）绕其中心（xcenter, ycenter)顺时针旋转&#952;角度后，新的坐标位置（x&#8242;, y&#8242;）的计算公式为：</p>
<p>xcenter = (right － left ＋ 1) ／ 2 ＋ left;<br />
ycenter = (bottom － top ＋ 1) ／ 2 ＋ top;<br />
x&#8242; = (x0 － xcenter) cos&#952; － (y0 － ycenter) sin&#952; ＋ xcenter;<br />
y&#8242; = (x0 － xcenter) sin&#952; ＋ (y0 － ycenter) cos&#952; ＋ ycenter; </p>
<br />
逆时针-&#952;
<img src ="http://www.blogjava.net/Todd/aggbug/348387.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Todd/" target="_blank">Todd</a> 2011-04-16 01:10 <a href="http://www.blogjava.net/Todd/archive/2011/04/16/348387.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>vs2008 生成“cl.exe”时出错。“MessageBoxW”: 不能将参数 2 从“char *”转换为“LPCWSTR”</title><link>http://www.blogjava.net/Todd/archive/2011/04/14/348264.html</link><dc:creator>Todd</dc:creator><author>Todd</author><pubDate>Wed, 13 Apr 2011 18:48:00 GMT</pubDate><guid>http://www.blogjava.net/Todd/archive/2011/04/14/348264.html</guid><wfw:comment>http://www.blogjava.net/Todd/comments/348264.html</wfw:comment><comments>http://www.blogjava.net/Todd/archive/2011/04/14/348264.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Todd/comments/commentRss/348264.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Todd/services/trackbacks/348264.html</trackback:ping><description><![CDATA[使用vs2008 编译，<br />
1）生成&#8220;cl.exe&#8221;时出错。<br />
================<br />
Microsoft Visual Studio 9.0\VC\bin下的c1.exe没有加载；相关环境变量丢失导致<br />
工具-&gt;选项-&gt;项目与解决方案-&gt;VC++目录，可执行文件下<br />
添加$(VCInstallDir)bin；<br />
问题解决<br />
<br />
<br />
2）&#8220;MessageBoxW&#8221;: 不能将参数 2 从&#8220;char *&#8221;转换为&#8220;LPCWSTR&#8221;<br />
=======================================================<br />
vs2008字符集问题，默认使用了 Unicode 字符集；<br />
WinUser.h下的一段代码<br />
#ifdef UNICODE<br />
#define MessageBox&nbsp; MessageBoxW<br />
#else<br />
#define MessageBox&nbsp; MessageBoxA<br />
#endif // !UNICODE<br />
由于MessageBox 就是调用MessageBoxW<br />
所以直接使用MessageBoxA函数，问题解决
<img src ="http://www.blogjava.net/Todd/aggbug/348264.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Todd/" target="_blank">Todd</a> 2011-04-14 02:48 <a href="http://www.blogjava.net/Todd/archive/2011/04/14/348264.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>jni javac++ 参数传递问题解决</title><link>http://www.blogjava.net/Todd/archive/2010/05/23/321655.html</link><dc:creator>Todd</dc:creator><author>Todd</author><pubDate>Sun, 23 May 2010 05:18:00 GMT</pubDate><guid>http://www.blogjava.net/Todd/archive/2010/05/23/321655.html</guid><wfw:comment>http://www.blogjava.net/Todd/comments/321655.html</wfw:comment><comments>http://www.blogjava.net/Todd/archive/2010/05/23/321655.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Todd/comments/commentRss/321655.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Todd/services/trackbacks/321655.html</trackback:ping><description><![CDATA[一，问题
<br />
1.多参数回传
<br />
2.参数传递出现乱码
<br />
<br />
二，解决
<br />
1.使用byte[]数组传入c++,在生成的头文件里就会变成jbyteArray 类型
<br />
例如，java 中参数：byte[]account,头文件里参数变成jbyteArray account，
<br />
通过c++修改完account的值后，java要获取该值，直接使用
<br />
jbyte* jbAccount = (env)-&gt;GetByteArrayElements(env, account, 0);
<br />
char* szAccount = (char*)jbAccount;
<br />
指针的地址并不是account的地址，最后赋下值才行
<br />
env-&gt;SetByteArrayRegion(account,0,strlen(szAccount),jbyte*
jbAccount);
<br />
<br />
2.String.getBytes()生成的byte数组传入c++后，在字符串的结尾会有多余乱码，
<br />
解决办法是，传入byte数组时，把数组的长度length，也传入c++,
<br />
令接受的数组strBuff[length]='\0';即可解决问题
<img src ="http://www.blogjava.net/Todd/aggbug/321655.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Todd/" target="_blank">Todd</a> 2010-05-23 13:18 <a href="http://www.blogjava.net/Todd/archive/2010/05/23/321655.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>矛与盾的较量（4）——奇妙的Base64编码</title><link>http://www.blogjava.net/Todd/archive/2010/05/20/321432.html</link><dc:creator>Todd</dc:creator><author>Todd</author><pubDate>Wed, 19 May 2010 17:48:00 GMT</pubDate><guid>http://www.blogjava.net/Todd/archive/2010/05/20/321432.html</guid><wfw:comment>http://www.blogjava.net/Todd/comments/321432.html</wfw:comment><comments>http://www.blogjava.net/Todd/archive/2010/05/20/321432.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Todd/comments/commentRss/321432.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Todd/services/trackbacks/321432.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 下载本节例子程序 (6.93 KB)各位看官应该都是资深的网虫了，小弟斗胆在此问问大家，平时上网时，除了泡MM、到论坛灌水、扔版砖&#8230;&#8230;之外，进行的最多的是什么活动？对了，你一定会说：是收发电子邮件！（谁敢说自己没收/发过电子邮件的？拉出去枪毙了！！）收/发E-mail的时候有一个安全性的问题——假想一下，你花了一整天时间给系花写的情书，在发送的过程中被隔壁宿...&nbsp;&nbsp;<a href='http://www.blogjava.net/Todd/archive/2010/05/20/321432.html'>阅读全文</a><img src ="http://www.blogjava.net/Todd/aggbug/321432.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Todd/" target="_blank">Todd</a> 2010-05-20 01:48 <a href="http://www.blogjava.net/Todd/archive/2010/05/20/321432.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>矛与盾的较量（3）——CRC实践篇</title><link>http://www.blogjava.net/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.blogjava.net/Todd/archive/2010/05/20/321431.html</guid><wfw:comment>http://www.blogjava.net/Todd/comments/321431.html</wfw:comment><comments>http://www.blogjava.net/Todd/archive/2010/05/20/321431.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Todd/comments/commentRss/321431.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Todd/services/trackbacks/321431.html</trackback:ping><description><![CDATA[<a href="http://www.luocong.com/articles/zipped/CRC32_Test.zip">下载本节例子程序</a> (13.4 KB)<br />
<strong>（特别感谢汇编高手 <font color="red">dREAMtHEATER</font> 对我的代码作出了相当好的优化！请参观他的<a href="http://notexpad.yeah.net/" target="_blank">主页</a>）</strong><br />
<br />
上一节里我们介绍了CRC-32的实现原理，可是原理不能当饭吃吧？下面让我们来看看CRC是怎么应用到文件保护上的&#8230;&#8230;<br />
<br />
（由于本文涉及到的源代码比较多，so请各位读者自行下载代码进行分析）<br />
<br />
在
《原理篇》里面，我们已经知道，通过对一个字符串进行CRC-32转换，最后可以得到一个4个字节长的CRC-32值，而且无论该字符串有多长，最终生成
的CRC-32值都肯定是4个字节长。这就给了我们一个启示：是否能够在一个文件的某个地方储存这个CRC-32值，然后在文件运行的时候，再读取这个
CRC-32值，进行比较？<br />
<br />
答案是肯定的。让我们先来看看PE文件的结构：（什么？你不懂PE文件结构？！那&#8230;&#8230;先去找点资料看看吧，到处都有的哦）<br />
<br />
在
PE的可选映像头（IMAGE_OPTIONAL_HEADER）里面，有一个保留字段：Win32Version，根据MSDN的资料，它的值一般是
0，而且它的长度是4个DWORD。呵呵，你是不是已经想到什么了呢？对了，它的长度和我们要储存的CRC-32正好是相等的，而且它的值是不变的，一般
是0（别问我为什么啊，我也不知道）。这就给我们提供了一个储存CRC-32空间的可能，而实际上，有很多Win32病毒也是利用这个
Win32Verion保留字段来储存它们的感染标志的。<br />
<br />
好了，明确了目标，我们来看看具体应该怎么实现：<br />
<br />
1、先写一个
第三方的程序，我假设它叫&#8220;AddCRC32ToFile.exe&#8221;。我们可以利用这个程序，打开一个文件，假设这个文件叫做
&#8220;CRC32_Test.exe&#8221;，然后&#8220;AddCRC32ToFile.exe&#8221;就会计算出&#8220;CRC32_Test.exe&#8221;的CRC-32值，并把这
个CRC-32值写入&#8220;CRC32_Test.exe&#8221;的Win32Version处。（其实这步要到最后才做的）<br />
<br />
2、写好需要进行保护
的程序，在这里我假设它叫做&#8220;CRC32_Test.exe&#8221;，记住一定要在这个程序里面加入CRC-32的校验模块。这个校验模块的工作过程是这样
的：a、先读取自身文件的所有内容，储存在一个字符串中，然后把这个字符串的Win32Version处的4个字节改成4个0，再把字符串进行CRC-
32转换，这时我们就得到了一个&#8220;原始&#8221;文件的CRC-32值；b、读取自身文件的Win32Version处的值，这个值是我们通过
&#8220;AddCRC32ToFile.exe&#8221;写进去的。最后我们把步骤a和b中得到的两个CRC-32值进行比较，如果相等的话，说明文件没有被修改过；反
之就说明文件已经被修改了。<br />
<br />
很复杂是吧？其实好好想一想，没啥困难的。关键是要按照以下步骤进行：<br />
<br />
1、一定要先在
&#8220;CRC32_Test.exe&#8221;里面写好所有的模块，然后才用&#8220;AddCRC32ToFile.exe&#8221;把&#8220;CRC32_Test.exe&#8221;的CRC-
32值写入&#8220;CRC32_Test.exe&#8221;的Win32Version处，否则最后得到的结果肯定是不正确的。顺序一定不能搞错！！！<br />
<br />
2、今后一旦修改了&#8220;CRC32_Test.exe&#8221;的内容（比如重新编译了一次），就一定要再用&#8220;AddCRC32ToFile.exe&#8221;重新把CRC-32值写入&#8220;CRC32_Test.exe&#8221;中去，否则结果也是会不正确的。<br />
<br />
其实方案不止这一种，还有以下的几种是可行的：<br />
1、把CRC-32的值写入一个单独的DLL文件中（或者别的什么乱七八糟的地方，随你的便），然后在运行的时候读取DLL文件中储存好的CRC-32值，进行比较。<br />
2、把CRC-32的值追加到.exe文件的最后，在运行的时候读取这最后的4个字节的内容，进行比较。不过我觉得这样做不太好，呵呵，因为增加了文件的长度。<br />
&#8230;&#8230;<br />
<br />
我的方案的缺点分析：<br />
CRC-32的值其实可以由Cracker自行计算得出后，重新写入到Win32Version处。这样的话，我们做的工作岂不是没有意义了？<br />
其
实解决的方法还是有的，我们可以在计算CRC-32值之前，对需要进行转换的字符串加点手脚，例如对这个字符串进行移位、xor等操作，或者把自己的生日
等信息加入到字符串中，随你的便什么都行，总之不是单纯的文件的内容就行了，然后在最后比较的时候，也用同样的方法反计算出CRC-32值。这样得到的
CRC-32就不是由文件的内容计算出来的，相信对Cracker的阻力也会加大不少。<br />
<br />
总结：<br />
应用CRC原理到文件的自校验保护中，是一种很灵活的手段，可用的方法有很多种。本文只是抛砖引玉，希望高手能给出更好的解决方法，并请发信到<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#108;&#99;&#111;&#116;&#104;&#101;&#114;&#64;&#49;&#54;&#51;&#46;&#110;&#101;&#116;&#63;&#115;&#117;&#98;&#106;&#101;&#99;&#116;&#61;&#37;&#69;&#56;&#37;&#56;&#48;&#37;&#56;&#49;&#37;&#69;&#55;&#37;&#66;&#68;&#37;&#57;&#55;&#37;&#69;&#70;&#37;&#66;&#67;&#37;&#56;&#67;&#37;&#69;&#54;&#37;&#57;&#67;&#37;&#56;&#57;&#37;&#69;&#53;&#37;&#56;&#53;&#37;&#66;&#51;&#67;&#82;&#67;&#45;&#51;&#50;&#37;&#69;&#55;&#37;&#57;&#65;&#37;&#56;&#52;&#37;&#69;&#57;&#37;&#57;&#55;&#37;&#65;&#69;&#37;&#69;&#57;&#37;&#65;&#50;&#37;&#57;&#56;&#37;&#69;&#54;&#37;&#56;&#51;&#37;&#66;&#51;&#37;&#69;&#56;&#37;&#66;&#55;&#37;&#57;&#70;&#37;&#69;&#52;&#37;&#66;&#68;&#37;&#65;&#48;&#37;&#69;&#55;&#37;&#65;&#48;&#37;&#57;&#52;&#37;&#69;&#55;&#37;&#65;&#57;&#37;&#66;&#54;&#37;&#69;&#70;&#37;&#66;&#67;&#37;&#56;&#49;" title="共同研究！">lcother@163.net</a>，我们共同研究，多谢！！！
<img src ="http://www.blogjava.net/Todd/aggbug/321431.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Todd/" target="_blank">Todd</a> 2010-05-20 01:47 <a href="http://www.blogjava.net/Todd/archive/2010/05/20/321431.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>矛与盾的较量（2）——CRC原理篇</title><link>http://www.blogjava.net/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.blogjava.net/Todd/archive/2010/05/20/321430.html</guid><wfw:comment>http://www.blogjava.net/Todd/comments/321430.html</wfw:comment><comments>http://www.blogjava.net/Todd/archive/2010/05/20/321430.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Todd/comments/commentRss/321430.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Todd/services/trackbacks/321430.html</trackback:ping><description><![CDATA[<a href="http://www.luocong.com/articles/zipped/CRC32_base.zip">下载本节例子程序</a> (4.29 KB)<br />
<strong>（特别感谢汇编高手 <font color="red">dREAMtHEATER</font> 对我的代码作出了相当好的优化！请参观他的<a href="http://notexpad.yeah.net/" target="_blank">主页</a>）</strong><br />
<br />
上一节我们介绍了花指令，不过花指令毕竟是一种很简单的东西，基本上入了门的Cracker都可以对付得了。所以，我们很有必要给自己的软件加上更好的保护。CRC校验就是其中的一种不错的方法。<br />
<br />
CRC
是什么东西呢？其实我们大家都不应该会对它陌生，回忆一下？你用过RAR和ZIP等压缩软件吗？它们是不是常常会给你一个恼人的&#8220;CRC校验错误&#8221;信息
呢？我想你应该明白了吧，CRC就是块数据的计算值，它的全称是&#8220;Cyclic Redundancy
Check&#8221;，中文名是&#8220;循环冗余码&#8221;，&#8220;CRC校验&#8221;就是&#8220;循环冗余校验&#8221;。（哇，真拗口，希望大家不要当我是唐僧，呵呵。^_^）<br />
<br />
CRC
有什么用呢？它的应用范围很广泛，最常见的就是在网络传输中进行信息的校对。其实我们大可以把它应用到软件保护中去，因为它的计算是非常非常非常严格的。
严格到什么程度呢？你的程序只要被改动了一个字节（甚至只是大小写的改动），它的值就会跟原来的不同。Hoho，是不是很厉害呢？所以只要给你的&#8220;原&#8221;程
序计算好CRC值，储存在某个地方，然后在程序中随机地再对文件进行CRC校验，接着跟第一次生成并保存好的CRC值进行比较，如果相等的话就说明你的程
序没有被修改/破解过，如果不等的话，那么很可能你的程序遭到了病毒的感染，或者被Cracker用16进制工具暴力破解过了。<br />
<br />
废话说完了，我们先来看看CRC的原理。<br />
（由于CRC实现起来有一定的难度，所以具体怎样用它来保护文件，留待下一节再讲。）<br />
<br />
首先看两个式子：<br />
式一：9 / 3 = 3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;（余数 = 0）<br />
式二：(9 + 2 ) / 3 = 3&nbsp;&nbsp; （余数 = 2）<br />
<br />
在小学里我们就知道，除法运算就是将被减数重复地减去除数X次，然后留下余数。<br />
所以上面的两个式子可以用二进制计算为：（什么？你不会二进制计算？我倒～～～）<br />
<br />
式一：<br />
1001&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--&gt; 9<br />
0011&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp; --&gt; 3<br />
---------<br />
0110&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--&gt; 6<br />
0011&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp; --&gt; 3<br />
---------<br />
0011&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--&gt; 3<br />
0011&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp; --&gt; 3<br />
---------<br />
0000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--&gt; 0，余数<br />
一共减了3次，所以商是3，而最后一次减出来的结果是0，所以余数为0<br />
<br />
式二：<br />
1011&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--&gt; 11<br />
0011&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp; --&gt; 3<br />
---------<br />
1000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--&gt; 8<br />
0011&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp; --&gt; 3<br />
---------<br />
0101&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--&gt; 5<br />
0011&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp; --&gt; 3<br />
---------<br />
0010&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--&gt; 2,余数<br />
一共减了3次，所以商是3，而最后一次减出来的结果是2，所以余数为2<br />
<br />
看明白了吧？很好，let&#8217;s go on!<br />
<br />
二进制减法运算的规则是，如果遇到0-1的情况，那么要从高位借1，就变成了(10+0)-1=1<br />
CRC运算有什么不同呢？让我们看下面的例子：<br />
<br />
这次用式子30 / 9，不过请读者注意最后的余数：<br />
<br />
11110&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--&gt; 30<br />
1001&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;&nbsp;--&gt; 9<br />
---------<br />
&nbsp;1100&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--&gt; 12&nbsp;&nbsp;&nbsp;&nbsp;（很奇怪吧？为什么不是21呢？）<br />
&nbsp;1001&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp;&nbsp;--&gt; 9<br />
&nbsp;--------<br />
&nbsp;&nbsp;101&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--&gt; 5，余数 --&gt; the CRC!<br />
<br />
这个式子的计算过程是不是很奇怪呢？它不是直接减的，而是用XOR的方式来运算（程序员应该都很熟悉XOR吧），最后得到一个余数。<br />
<br />
对啦，这个就是CRC的运算方法，明白了吗？CRC的本质是进行XOR运算，运算的过程我们不用管它，因为运算过程对最后的结果没有意义；我们真正感兴趣的只是最终得到的余数，这个余数就是CRC值。<br />
<br />
进行一个CRC运算我们需要选择一个除数，这个除数我们叫它为&#8220;poly&#8221;，宽度W就是最高位的位置，所以我刚才举的例子中的除数9，这个poly 1001的W是3，而不是4，注意最高位总是1。（别问为什么，这个是规定）<br />
<br />
如果我们想计算一个位串的CRC码，我们想确定每一个位都被处理过，因此，我们要在目标位串后面加上W个0位。现在让我们根据CRC的规范来改写一下上面的例子：<br />
<br />
Poly&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;&nbsp;&nbsp;&nbsp;1001，宽度W = 3<br />
位串Bitstring&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;&nbsp;&nbsp;&nbsp;11110<br />
Bitstring + W zeroes&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;&nbsp;&nbsp;&nbsp;11110 + 000 = 11110000<br />
<br />
11110000<br />
1001||||&nbsp;&nbsp;&nbsp;&nbsp;-<br />
-------------<br />
&nbsp;1100|||<br />
&nbsp;1001|||&nbsp;&nbsp;&nbsp;&nbsp;-<br />
&nbsp;------------<br />
&nbsp;&nbsp;1010||<br />
&nbsp;&nbsp;1001||&nbsp;&nbsp;&nbsp;&nbsp;-<br />
&nbsp;&nbsp;-----------<br />
&nbsp;&nbsp; 0110|<br />
&nbsp;&nbsp; 0000|&nbsp;&nbsp;&nbsp;&nbsp;-<br />
&nbsp;&nbsp; ----------<br />
&nbsp;&nbsp;&nbsp;&nbsp;1100<br />
&nbsp;&nbsp;&nbsp;&nbsp;1001&nbsp;&nbsp;&nbsp;&nbsp;-<br />
&nbsp;&nbsp;&nbsp;&nbsp;---------<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;101&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--&gt; 5，余数 --&gt; the CRC!<br />
<br />
还有两点重要声明如下：<br />
1、只有当Bitstring的最高位为1，我们才将它与poly进行XOR运算，否则我们只是将Bitstring左移一位。<br />
2、XOR运算的结果就是被操作位串Bitstring与poly的低W位进行XOR运算，因为最高位总为0。<br />
<br />
呵呵，是不是有点头晕脑胀的感觉了？看不懂的话，再从头看一遍，其实是很好理解的。（就是一个XOR运算嘛！）<br />
<br />
<br />
好啦，原理介绍到这里，下面我讲讲具体怎么编程。<br />
<br />
由于速度的关系，CRC的实现主要是通过查表法，对于CRC-16和CRC-32，各自有一个现成的表，大家可以直接引入到程序中使用。（由于这两个表太长，在这里不列出来了，请读者自行在网络上查找，很容易找到的。）<br />
<br />
如果我们没有这个表怎么办呢？或者你跟我一样，懒得自己输入？不用急，我们可以&#8220;自己动手，丰衣足食&#8221;。<br />
你可能会说，自己编程来生成这个表，会不会太慢了？其实大可不必担心，因为我们是在汇编代码的级别进行运算的，而这个表只有区区256个双字，根本影响不了速度。<br />
<br />
这个表的C语言描述如下：<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">&lt;</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">&nbsp;&nbsp;&nbsp;&nbsp;crc <font color="#3080ca">=</font> i<font color="#9932cd"><strong>;</strong></font><br />
            </a><a name="L4">&nbsp;&nbsp;&nbsp;&nbsp;<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">&lt;</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">&nbsp;&nbsp;&nbsp;&nbsp;<font color="#db3098">{</font><br />
            </a><a name="L6">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">if</font> <font color="#ff00ff">(</font>crc <font color="#3080ca">&amp;</font> <font color="#802000">1</font><font color="#ff00ff">)</font><br />
            </a><a name="L7">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;crc <font color="#3080ca">=</font> <font color="#ff00ff">(</font>crc <font color="#3080ca">&gt;&gt;</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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">else</font><br />
            </a><a name="L9">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;crc <font color="#3080ca">&gt;&gt;=</font> <font color="#802000">1</font><font color="#9932cd"><strong>;</strong></font><br />
            </a><a name="L10">&nbsp;&nbsp;&nbsp;&nbsp;<font color="#db3098">}</font><br />
            </a><a name="L11">&nbsp;&nbsp;&nbsp;&nbsp;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 />
生成表之后，就可以进行运算了。<br />
我们的算法如下：<br />
1、将寄存器向右边移动一个字节。<br />
2、将刚移出的那个字节与我们的字符串中的新字节进行XOR运算，得出一个指向值表table[0..255]的索引。<br />
3、将索引所指的表值与寄存器做XOR运算。<br />
4、如果数据没有全部处理完，则跳到步骤1。<br />
<br />
这个算法的C语言描述如下：<br />
<br />
<table bgcolor="#fbedbb" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td><a name="L1">&nbsp;&nbsp;&nbsp;&nbsp;temp <font color="#3080ca">=</font> <font color="#ff00ff">(</font>oldcrc <font color="#3080ca">^</font> abyte<font color="#ff00ff">)</font> <font color="#3080ca">&amp;</font> <font color="#802000">0x000000FF</font><font color="#9932cd"><strong>;</strong></font><br />
            </a><a name="L2">&nbsp;&nbsp;&nbsp;&nbsp;crc&nbsp;&nbsp;<font color="#3080ca">=</font> <font color="#ff00ff">(</font><font color="#ff00ff">(</font> oldcrc <font color="#3080ca">&gt;&gt;</font> <font color="#802000">8</font><font color="#ff00ff">)</font> <font color="#3080ca">&amp;</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">&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">return</font> crc<font color="#9932cd"><strong>;</strong></font></a></td>
        </tr>
    </tbody>
</table>
<br />
好啦，所有的东东都说完啦，最后献上一个完整的Win32Asm例子，请读者仔细研究吧！<br />
（汇编方面的CRC-32资料极少啊，我个人认为下面给出的是很宝贵的资料。）<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">;程序名称：演示CRC32原理</font><br />
            </a><a name="L3"><font color="#238e23">;作者：罗聪</font><br />
            </a><a name="L4"><font color="#238e23">;日期：2002-8-24</font><br />
            </a><a name="L5"><font color="#238e23">;出处：http://laoluoc.yeah.net（老罗的缤纷天地）</font><br />
            </a><a name="L6"><font color="#238e23">;注意事项：如欲转载，请保持本程序的完整，并注明：转载自&#8220;老罗的缤纷天地&#8221;（http://laoluoc.yeah.net）</font><br />
            </a><a name="L7"><font color="#238e23">;</font><br />
            </a><a name="L8"><font color="#238e23">;特别感谢Win32ASM高手—— dREAMtHEATER 为我的代码作了相当好的优化！</font><br />
            </a><a name="L9"><font color="#238e23">;请各位前去 http://NoteXPad.yeah.net 下载他的小巧的&#8220;cool 记事本&#8221;—— NoteXPad 来试用！（100% Win32ASM 编写）</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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<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&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">proto</font><br />
            </a><a name="L25">arraycrc32&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">equ</font>&nbsp;&nbsp;&nbsp;&nbsp;<font color="#802000">3000</font><br />
            </a><a name="L29">IDC_EDIT_INPUT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font color="#ff0000">equ</font>&nbsp;&nbsp;&nbsp;&nbsp;<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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font color="#ff0000">db</font>&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">"lc_dialog"</font><font color="#9932cd"><strong>,</strong></font> <font color="#802000">0</font><br />
            </a><a name="L33">szTitle&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font color="#ff0000">db</font>&nbsp;&nbsp;&nbsp;&nbsp;<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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">db</font>&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">"字符串 ""%s"" 的 CRC32 值是：%X"</font><font color="#9932cd"><strong>,</strong></font> <font color="#802000">0</font><br />
            </a><a name="L35">crc32tbl&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">dd</font>&nbsp;&nbsp;&nbsp;&nbsp;<font color="#802000">256</font> <font color="#ff0000">dup</font><font color="#ff00ff">(</font><font color="#802000">0</font><font color="#ff00ff">)</font>&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;CRC-32 table</font><br />
            </a><a name="L36">szBuffer&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">db</font>&nbsp;&nbsp;&nbsp;&nbsp;<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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">db</font>&nbsp;&nbsp;&nbsp;&nbsp;<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">&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">invoke</font> GetModuleHandle<font color="#9932cd"><strong>,</strong></font> NULL<br />
            </a><a name="L44">&nbsp;&nbsp;&nbsp;&nbsp;<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">&nbsp;&nbsp;&nbsp;&nbsp;<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">&nbsp;&nbsp;&nbsp;&nbsp;<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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
            </a><a name="L52">&nbsp;&nbsp;&nbsp;&nbsp;<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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">mov</font> <font color="#ff0000">eax</font><font color="#9932cd"><strong>,</strong></font>wParam<br />
            </a><a name="L54">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
            </a><a name="L61">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;******************************************</font><br />
            </a><a name="L62">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;关键代码开始：（当当当当&#8230;&#8230;）</font><br />
            </a><a name="L63">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;******************************************</font><br />
            </a><a name="L64">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;取得用户输入的字符串：</font><br />
            </a><a name="L65">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;初始化crc32table：</font><br />
            </a><a name="L68">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">invoke</font> init_crc32table<br />
            </a><a name="L69"><br />
            </a><a name="L70">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;下面赋值给寄存器ebx，以便进行crc32转换：</font><br />
            </a><a name="L71">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;EBX是待转换的字符串的首地址：</font><br />
            </a><a name="L72">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;进行crc32转换：</font><br />
            </a><a name="L75">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">invoke</font> arraycrc32<br />
            </a><a name="L76"><br />
            </a><a name="L77">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;格式化输出：</font><br />
            </a><a name="L78">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;好啦，让我们显示结果：</font><br />
            </a><a name="L81">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#9932cd"><strong>.</strong></font><font color="#ff0000">ENDIF</font><br />
            </a><a name="L83">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#9932cd"><strong>.</strong></font><font color="#ff0000">endif</font><br />
            </a><a name="L84">&nbsp;&nbsp;&nbsp;&nbsp;<font color="#9932cd"><strong>.</strong></font><font color="#ff0000">ELSE</font><br />
            </a><a name="L85">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">mov</font> <font color="#ff0000">eax</font><font color="#9932cd"><strong>,</strong></font>FALSE<br />
            </a><a name="L86">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">ret</font><br />
            </a><a name="L87">&nbsp;&nbsp;&nbsp;&nbsp;<font color="#9932cd"><strong>.</strong></font><font color="#ff0000">ENDIF</font><br />
            </a><a name="L88">&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">mov</font> <font color="#ff0000">eax</font><font color="#9932cd"><strong>,</strong></font>TRUE<br />
            </a><a name="L89">&nbsp;&nbsp;&nbsp;&nbsp;<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">;函数功能：生成CRC-32表</font><br />
            </a><a name="L94"><font color="#238e23">;**********************************************************</font><br />
            </a><a name="L95">init_crc32table&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">proc</font><br />
            </a><a name="L96"><br />
            </a><a name="L97">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;如果用C语言来表示，应该如下：</font><br />
            </a><a name="L98">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;</font><br />
            </a><a name="L99">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;&nbsp;&nbsp;&nbsp;&nbsp;for (i = 0; i &lt; 256; i++)</font><br />
            </a><a name="L100">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;&nbsp;&nbsp;&nbsp;&nbsp;{</font><br />
            </a><a name="L101">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;crc = i;</font><br />
            </a><a name="L102">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (j = 0; j &lt; 8; j++)</font><br />
            </a><a name="L103">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</font><br />
            </a><a name="L104">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (crc &amp; 1)</font><br />
            </a><a name="L105">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;crc = (crc &gt;&gt; 1) ^ 0xEDB88320;</font><br />
            </a><a name="L106">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else</font><br />
            </a><a name="L107">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;crc &gt;&gt;= 1;</font><br />
            </a><a name="L108">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</font><br />
            </a><a name="L109">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;crc32tbl[i] = crc;</font><br />
            </a><a name="L110">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;&nbsp;&nbsp;&nbsp;&nbsp;}</font><br />
            </a><a name="L111">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;</font><br />
            </a><a name="L112">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;呵呵，让我们把上面的语句改成assembly的：</font><br />
            </a><a name="L113"><br />
            </a><a name="L114">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">mov</font>&nbsp;&nbsp;&nbsp;&nbsp; <font color="#ff0000">ecx</font><font color="#9932cd"><strong>,</strong></font> <font color="#802000">256</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">; repeat for every DWORD in table</font><br />
            </a><a name="L115">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">mov</font>&nbsp;&nbsp;&nbsp;&nbsp; <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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">lea</font>&nbsp;&nbsp;&nbsp;&nbsp; <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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">push</font>&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">ecx</font><br />
            </a><a name="L119">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">mov</font>&nbsp;&nbsp;&nbsp;&nbsp; <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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">shr</font>&nbsp;&nbsp;&nbsp;&nbsp; <font color="#ff0000">eax</font><font color="#9932cd"><strong>,</strong></font> <font color="#802000">1</font><br />
            </a><a name="L122">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">jnc</font>&nbsp;&nbsp;&nbsp;&nbsp; @F<br />
            </a><a name="L123">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">xor</font>&nbsp;&nbsp;&nbsp;&nbsp; <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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">dec</font>&nbsp;&nbsp;&nbsp;&nbsp; <font color="#ff0000">ecx</font><br />
            </a><a name="L126">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">jne</font>&nbsp;&nbsp;&nbsp;&nbsp; <font color="#802000">$SmallLoop</font><br />
            </a><a name="L127">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">pop</font>&nbsp;&nbsp;&nbsp;&nbsp; <font color="#ff0000">ecx</font><br />
            </a><a name="L128">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">mov</font>&nbsp;&nbsp;&nbsp;&nbsp; <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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">dec</font>&nbsp;&nbsp;&nbsp;&nbsp; <font color="#ff0000">ecx</font><br />
            </a><a name="L130">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">jne</font>&nbsp;&nbsp;&nbsp;&nbsp; <font color="#802000">$BigLoop</font><br />
            </a><a name="L131"><br />
            </a><a name="L132">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">ret</font><br />
            </a><a name="L133">init_crc32table&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<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">;函数功能：计算CRC-32</font><br />
            </a><a name="L138"><font color="#238e23">;**************************************************************</font><br />
            </a><a name="L139">arraycrc32&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">proc</font><br />
            </a><a name="L140"><br />
            </a><a name="L141">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;计算 CRC-32 ，我采用的是把整个字符串当作一个数组，然后把这个数组的首地址赋值给 EBX，把数组的长度赋值给 ECX，然后循环计算，返回值（计算出来的 CRC-32 值）储存在 EAX 中：</font><br />
            </a><a name="L142">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;</font><br />
            </a><a name="L143">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">; 参数：</font><br />
            </a><a name="L144">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EBX = address of first byte</font><br />
            </a><a name="L145">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">; 返回值：</font><br />
            </a><a name="L146">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EAX = CRC-32 of the entire array</font><br />
            </a><a name="L147">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EBX = ?</font><br />
            </a><a name="L148">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ECX = 0</font><br />
            </a><a name="L149">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EDX = ?</font><br />
            </a><a name="L150"><br />
            </a><a name="L151">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">mov</font>&nbsp;&nbsp;&nbsp;&nbsp; <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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">or</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">ebx</font><font color="#9932cd"><strong>,</strong></font> <font color="#ff0000">ebx</font><br />
            </a><a name="L153">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">jz</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#802000">$Done</font>&nbsp;&nbsp; <font color="#238e23">; 避免出现空指针</font><br />
            </a><a name="L154">@@<font color="#3080ca">:</font><br />
            </a><a name="L155">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">mov</font>&nbsp;&nbsp;&nbsp;&nbsp; <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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">or</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">dl</font><font color="#9932cd"><strong>,</strong></font> <font color="#ff0000">dl</font><br />
            </a><a name="L157">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">je</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#802000">$Done</font>&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;判断是否对字符串扫描完毕</font><br />
            </a><a name="L158">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
            </a><a name="L159"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;这里我用查表法来计算 CRC-32 ，因此非常快速：</font><br />
            </a><a name="L160">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;因为这是assembly代码，所以不需要给这个过程传递参数，只需要把oldcrc赋值给EAX，以及把byte赋值给DL：</font><br />
            </a><a name="L161">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;</font><br />
            </a><a name="L162">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">; 在C语言中的形式：</font><br />
            </a><a name="L163">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;</font><br />
            </a><a name="L164">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;&nbsp;&nbsp; temp = (oldcrc ^ abyte) &amp; 0x000000FF;</font><br />
            </a><a name="L165">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;&nbsp;&nbsp; crc&nbsp;&nbsp;= (( oldcrc &gt;&gt; 8) &amp; 0x00FFFFFF) ^ crc32tbl[temp];</font><br />
            </a><a name="L166">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;</font><br />
            </a><a name="L167">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">; 参数：</font><br />
            </a><a name="L168">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EAX = old CRC-32</font><br />
            </a><a name="L169">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DL = a byte</font><br />
            </a><a name="L170">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">; 返回值：</font><br />
            </a><a name="L171">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EAX = new CRC-32</font><br />
            </a><a name="L172">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#238e23">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EDX = ?</font><br />
            </a><a name="L173">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
            </a><a name="L174">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">xor</font>&nbsp;&nbsp;&nbsp;&nbsp; <font color="#ff0000">dl</font><font color="#9932cd"><strong>,</strong></font> <font color="#ff0000">al</font><br />
            </a><a name="L175">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">movzx</font>&nbsp;&nbsp; <font color="#ff0000">edx</font><font color="#9932cd"><strong>,</strong></font> <font color="#ff0000">dl</font><br />
            </a><a name="L176">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">shr</font>&nbsp;&nbsp;&nbsp;&nbsp; <font color="#ff0000">eax</font><font color="#9932cd"><strong>,</strong></font> <font color="#802000">8</font><br />
            </a><a name="L177">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">xor</font>&nbsp;&nbsp;&nbsp;&nbsp; <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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
            </a><a name="L179">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">inc</font>&nbsp;&nbsp;&nbsp;&nbsp; <font color="#ff0000">ebx</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
            </a><a name="L180">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">jmp</font>&nbsp;&nbsp;&nbsp;&nbsp; @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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">not</font>&nbsp;&nbsp;&nbsp;&nbsp; <font color="#ff0000">eax</font><br />
            </a><a name="L184">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">ret</font><br />
            </a><a name="L185">arraycrc32&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<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">;********************&nbsp;&nbsp;&nbsp;&nbsp;over&nbsp;&nbsp;&nbsp;&nbsp;********************</font><br />
            </a><a name="L189"><font color="#238e23">;by LC</font></a></td>
        </tr>
    </tbody>
</table>
<br />
<br />
下面是它的资源文件：<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&nbsp;&nbsp;&nbsp;&nbsp;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 />
            &nbsp;&nbsp;&nbsp;&nbsp;WS_SYSMENU<br />
            CAPTION "lc&#8217;s assembly framework"<br />
            FONT 9, "宋体", 0, 0, 0x0<br />
            BEGIN<br />
            &nbsp;&nbsp;&nbsp;&nbsp;LTEXT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "请输入一个字符串（区分大小写）：",IDC_STATIC,11,7,130,10<br />
            &nbsp;&nbsp;&nbsp;&nbsp;EDITTEXT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IDC_EDIT_INPUT,11,20,173,12,ES_AUTOHSCROLL<br />
            &nbsp;&nbsp;&nbsp;&nbsp;DEFPUSHBUTTON&nbsp;&nbsp; "Ca&amp;lc",IDC_BUTTON_OPEN,71,39,52,15<br />
            END</strong></td>
        </tr>
    </tbody>
</table>
<br />
<br />
如果你能够完全理解本节的内容，那么请留意我的下一讲，我将具体介绍如何运用CRC-32对你的文件进行保护。（呵呵，好戏在后头&#8230;&#8230;）
<img src ="http://www.blogjava.net/Todd/aggbug/321430.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Todd/" target="_blank">Todd</a> 2010-05-20 01:45 <a href="http://www.blogjava.net/Todd/archive/2010/05/20/321430.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>矛与盾的较量（1）——花指令【转自老罗】</title><link>http://www.blogjava.net/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.blogjava.net/Todd/archive/2010/05/20/321429.html</guid><wfw:comment>http://www.blogjava.net/Todd/comments/321429.html</wfw:comment><comments>http://www.blogjava.net/Todd/archive/2010/05/20/321429.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Todd/comments/commentRss/321429.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Todd/services/trackbacks/321429.html</trackback:ping><description><![CDATA[<p>
有矛就有盾。<br />
所以我们要讨论加密技术。<br />
<br />
我们知道，所有的编译型语
言，例如VC、BCB、Delphi和Win32ASM&#8230;&#8230;最终都会把源代码编译成机器能识别的0和1——因此也能够反过来把这些0和1反编译成汇编代
码。反编译有什么用呢？试想想，你辛辛苦苦写了一个perfect的软件出来，正准备把它卖上100万份，忽然！在市面上出现了很多仿制你的东
西&#8230;&#8230;hoho，不知道你会怎么想呢？反正我是会欲哭无泪的。还有另外一种情况，你的软件是用注册码的形式来授权的，每份license要卖30个美刀。
呵呵，正当你在考虑着一年后是去加利福尼亚还是夏威夷度假的时候，你的软件被Crack了——也就是说，你一分钱都不会得到&#8230;&#8230;（啊！我想跳楼啦！！）<br />
<br />
所以我们要讨论如何给自己的程序加密。这次就先说说最简单的花指令。<br />
<br />
在解释这个&#8220;花指令&#8221;之前，不妨先做几个小小的实验。<br />
<br />
我们先来写一个程序，命名为hua.asm，内容如下：<br />
<br />
<table bgcolor="#cccccc" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td>;***************************************************************<br />
            ;花指令实验1<br />
            ;作者：罗聪<br />
            ;日期：2002-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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;db&nbsp;&nbsp;&nbsp;&nbsp;"嘿嘿，这是一个花指令程序&#8230;&#8230;", 0<br />
            szCaption&nbsp;&nbsp;&nbsp;&nbsp;db&nbsp;&nbsp;&nbsp;&nbsp;"花指令演示 by LC 2002-8-21", 0<br />
            <br />
            .code<br />
            main:<br />
            &nbsp;&nbsp;&nbsp;&nbsp;jmp Do_It<br />
            Do_It:<br />
            &nbsp;&nbsp;&nbsp;&nbsp;invoke MessageBox, NULL, addr szText, addr szCaption, MB_OK<br />
            &nbsp;&nbsp;&nbsp;&nbsp;invoke ExitProcess, 0<br />
            end main</td>
        </tr>
    </tbody>
</table>
<br />
<br />
然后用W32Dasm v10来反编译它，得到的结果如下：（由于篇幅所限，这里只列出关键部分）<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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jmp 00401002<br />
            <br />
            * Referenced by a (U)nconditional or ?onditional Jump at Address:<br />
            |:00401000(U)<br />
            |<br />
            :00401002 6A00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push 00000000<br />
            <br />
            * Possible StringData Ref from Data Obj -&gt;"花指令演示 by LC 2002-8-21"<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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<br />
            :00401004 681F304000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push 0040301F<br />
            <br />
            * Possible StringData Ref from Data Obj -&gt;"嘿嘿，这是一个花指令程序&#8230;&#8230;"<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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<br />
            :00401009 6800304000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push 00403000<br />
            :0040100E 6A00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push 00000000<br />
            <br />
            * Reference To: USER32.MessageBoxA, Ord:01BBh<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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<br />
            :00401010 E80D000000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Call 00401022<br />
            :00401015 6A00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push 00000000<br />
            <br />
            * Reference To: KERNEL32.ExitProcess, Ord:0075h<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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<br />
            :00401017 E800000000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Call 0040101C<br />
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
哇，好夸张啊！你可能会说。反编译出来的代码几乎是跟源代码一一对应的，这样一来？我们的程序还有什么秘密可言呢？完全可以从反编译的结果中理解程序的功能。<br />
<br />
而且我们还可以在W32Dasm的&#8220;String Data References&#8221;中得到：<br />
<table bgcolor="#cccccc" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td>"嘿嘿，这个是一个花指令程序&#8230;&#8230;"<br />
            "花指令演示 by LC 2002-8-21"<br />
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
把刚才的源程序稍做修改，来做第二个实验：<br />
<br />
<br />
<table bgcolor="#cccccc" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td>;***************************************************************<br />
            ;花指令实验2<br />
            ;作者：罗聪<br />
            ;日期：2002-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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;db&nbsp;&nbsp;&nbsp;&nbsp;"嘿嘿，这是一个花指令程序&#8230;&#8230;", 0<br />
            szCaption&nbsp;&nbsp;&nbsp;&nbsp;db&nbsp;&nbsp;&nbsp;&nbsp;"花指令演示 by LC 2002-8-21", 0<br />
            <br />
            .code<br />
            main:<br />
            &nbsp;&nbsp;&nbsp;&nbsp;jz Do_It&nbsp;&nbsp;&nbsp;&nbsp;;注意这里和第一个实验中的源程序的区别<br />
            &nbsp;&nbsp;&nbsp;&nbsp;jnz Do_It&nbsp;&nbsp;&nbsp;&nbsp;;注意这里和第一个实验中的源程序的区别<br />
            Do_It:<br />
            &nbsp;&nbsp;&nbsp;&nbsp;invoke MessageBox, NULL, addr szText, addr szCaption, MB_OK<br />
            end main<br />
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
用W32Dasm反编译一下：<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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;je 00401004<br />
            :00401002 7500&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jne 00401004<br />
            <br />
            * Referenced by a (U)nconditional or ?onditional Jump at Addresses:<br />
            |:00401000?, :00401002?<br />
            |<br />
            :00401004 6A00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push 00000000<br />
            <br />
            * Possible StringData Ref from Data Obj -&gt;"花指令演示 by LC 2002-8-21"<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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<br />
            :00401006 681F304000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push 0040301F<br />
            <br />
            * Possible StringData Ref from Data Obj -&gt;"嘿嘿，这是一个花指令程序&#8230;&#8230;"<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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<br />
            :0040100B 6800304000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push 00403000<br />
            :00401010 6A00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push 00000000<br />
            <br />
            * Reference To: USER32.MessageBoxA, Ord:01BBh<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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<br />
            :00401012 E801000000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Call 00401018<br />
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
可以看出，这时的W32Dasm反编译出来的汇编指令还是正确的。但是W32Dasm其实已经逐渐落入我们设下的&#8220;陷阱&#8221;了。<br />
<br />
下面我们来做第三个实验，把源程序改成：<br />
<br />
<table bgcolor="#cccccc" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td>;***************************************************************<br />
            ;花指令实验3<br />
            ;作者：罗聪<br />
            ;日期：2002-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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;db&nbsp;&nbsp;&nbsp;&nbsp;"嘿嘿，这是一个花指令程序&#8230;&#8230;", 0<br />
            szCaption&nbsp;&nbsp;&nbsp;&nbsp;db&nbsp;&nbsp;&nbsp;&nbsp;"花指令演示 by LC 2002-8-21", 0<br />
            <br />
            .code<br />
            main:<br />
            &nbsp;&nbsp;&nbsp;&nbsp;jz Do_It&nbsp;&nbsp;&nbsp;&nbsp;;注意这里和第一个实验中的源程序的区别<br />
            &nbsp;&nbsp;&nbsp;&nbsp;jnz Do_It&nbsp;&nbsp;&nbsp;&nbsp;;注意这里和第一个实验中的源程序的区别<br />
            &nbsp;&nbsp;&nbsp;&nbsp;db 0E8h&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;注意这里和第二个实验中的源程序的区别<br />
            Do_It:<br />
            &nbsp;&nbsp;&nbsp;&nbsp;invoke MessageBox, NULL, addr szText, addr szCaption, MB_OK<br />
            &nbsp;&nbsp;&nbsp;&nbsp;invoke ExitProcess, 0<br />
            end main<br />
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
我们来看看W32Dasm中反编译出来的东西：<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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;je 00401005<br />
            :00401002 7501&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jne 00401005<br />
            :00401004 E86A00681D&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;call 1DA81073<br />
            :00401009 304000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xor byte ptr [eax+00], al<br />
            <br />
            * Possible StringData Ref from Data Obj -&gt;"嘿嘿，这是一个花指令程序&#8230;&#8230;"<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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<br />
            :0040100C 6800304000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push 00403000<br />
            :00401011 6A00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push 00000000<br />
            <br />
            * Reference To: USER32.MessageBoxA, Ord:01BBh<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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<br />
            :00401013 E80E000000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Call 00401026<br />
            :00401018 6A00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push 00000000<br />
            <br />
            * Reference To: KERNEL32.ExitProcess, Ord:0075h<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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<br />
            :0040101A E801000000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Call 00401020<br />
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
呵呵，很明显了，这时的 00401004 到 00401009 行出错了，而且这时查看&#8220;String Data References&#8221;，也只剩下了：<br />
<table bgcolor="#cccccc" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td>"嘿嘿，这是一个花指令程序&#8230;&#8230;"</td>
        </tr>
    </tbody>
</table>
<br />
<br />
让我们进一步隐藏信息，做第四个实验：<br />
<br />
<table bgcolor="#cccccc" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td>;***************************************************************<br />
            ;花指令实验4<br />
            ;作者：罗聪<br />
            ;日期：2002-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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;db&nbsp;&nbsp;&nbsp;&nbsp;"嘿嘿，这是一个花指令程序&#8230;&#8230;", 0<br />
            szCaption&nbsp;&nbsp;&nbsp;&nbsp;db&nbsp;&nbsp;&nbsp;&nbsp;"花指令演示 by LC 2002-8-21", 0<br />
            <br />
            .code<br />
            main:<br />
            &nbsp;&nbsp;&nbsp;&nbsp;jz Do_It&nbsp;&nbsp;&nbsp;&nbsp;;注意这里和第一个实验中的源程序的区别<br />
            &nbsp;&nbsp;&nbsp;&nbsp;jnz Do_It&nbsp;&nbsp;&nbsp;&nbsp;;注意这里和第一个实验中的源程序的区别<br />
            &nbsp;&nbsp;&nbsp;&nbsp;db 0E8h&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;注意这里和第二个实验中的源程序的区别<br />
            Do_It:<br />
            &nbsp;&nbsp;&nbsp;&nbsp;lea eax, szText&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;注意这里和第三个实验中的源程序的区别<br />
            &nbsp;&nbsp;&nbsp;&nbsp;lea ebx, szCaption&nbsp;&nbsp;&nbsp;&nbsp;;注意这里和第三个实验中的源程序的区别<br />
            &nbsp;&nbsp;&nbsp;&nbsp;invoke MessageBox, NULL, eax, ebx, MB_OK&nbsp;&nbsp;&nbsp;&nbsp;;注意这里和第三个实验中的源程序的区别<br />
            &nbsp;&nbsp;&nbsp;&nbsp;invoke ExitProcess, 0<br />
            end main<br />
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
编译，再用W32Dasm反编译，得到的是：<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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;je 00401005<br />
            :00401002 7501&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jne 00401005<br />
            :00401004 E88D050030&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;call 30401596<br />
            :00401009 40&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inc eax<br />
            :0040100A 008D1D1D3040&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;add byte ptr [ebp+40301D1D], cl<br />
            :00401010 006A00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;add byte ptr [edx+00], ch<br />
            :00401013 53&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push ebx<br />
            :00401014 50&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push eax<br />
            :00401015 6A00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push 00000000<br />
            <br />
            * Reference To: USER32.MessageBoxA, Ord:01BBh<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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<br />
            :00401017 E80E000000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Call 0040102A<br />
            :0040101C 6A00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push 00000000<br />
            <br />
            * Reference To: KERNEL32.ExitProcess, Ord:0075h<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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<br />
            :0040101E E801000000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Call 00401024<br />
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
呵呵，这次不但面目全非了，而且&#8220;String Data References&#8221;按钮已经变成了灰色。什么蛛丝马迹都没有了。<br />
<br />
各位看官看到这里明白了吗？其实花指令就是人为地构造一些&#8220;陷阱&#8221;和一些无用的字节。例如第二个实验中的：<br />
<br />
jz Do_It<br />
jnz Do_It<br />
<br />
其实这个跟 jmp Do_It 还不是一样吗？（呵呵，如果在大学的期末考试里这样写，一定会被判不及格&#8230;&#8230;）<br />
<br />
是的，其实程序原有的功能和逻辑还是一样的，我们只不过是换了一种表现形式而已。然而，反编译工具是没有人脑那么智能的，它们往往就会把这些指令理解错，从而错误地确定了指令的起始位置。<br />
<br />
要实现这种绝对跳转的功能，还可以用很多的方法，例如：<br />
<br />
Push Do_It<br />
ret<br />
<br />
<br />
<strong>花指令是很容易理解的，不过大家要注意适时而用，不要滥用啊，能起到迷惑破解者和隐藏信息的作用就行了，不然将来要维护代码时，我怕被迷惑的反而是你自己哦，呵呵&#8230;&#8230;</strong>
</p>
<img src ="http://www.blogjava.net/Todd/aggbug/321429.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Todd/" target="_blank">Todd</a> 2010-05-20 01:44 <a href="http://www.blogjava.net/Todd/archive/2010/05/20/321429.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>